synched with trunk at revision 36569
[blender-staging.git] / source / gameengine / Ketsji / KX_PythonInit.cpp
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  * Initialize Python thingies.
29  */
30
31 /** \file gameengine/Ketsji/KX_PythonInit.cpp
32  *  \ingroup ketsji
33  */
34
35
36 #include "GL/glew.h"
37
38 #if defined(WIN32) && !defined(FREE_WINDOWS)
39 #pragma warning (disable : 4786)
40 #endif //WIN32
41
42 #ifdef WITH_PYTHON
43
44 #ifdef _POSIX_C_SOURCE
45 #undef _POSIX_C_SOURCE
46 #endif
47
48 #ifdef _XOPEN_SOURCE
49 #undef _XOPEN_SOURCE
50 #endif
51
52 #include <Python.h>
53
54 extern "C" {
55         #include "bpy_internal_import.h"  /* from the blender python api, but we want to import text too! */
56         #include "py_capi_utils.h"
57         #include "mathutils.h" // Blender.Mathutils module copied here so the blenderlayer can use.
58         #include "bgl.h"
59         #include "blf_py_api.h"
60
61         #include "marshal.h" /* python header for loading/saving dicts */
62 }
63
64 #include "AUD_PyInit.h"
65
66 #endif
67
68 #include "KX_PythonInit.h"
69
70 // directory header for py function getBlendFileList
71 #ifndef WIN32
72   #include <dirent.h>
73   #include <stdlib.h>
74 #else
75   #include <io.h>
76   #include "BLI_winstuff.h"
77 #endif
78
79 //python physics binding
80 #include "KX_PyConstraintBinding.h"
81
82 #include "KX_KetsjiEngine.h"
83 #include "KX_RadarSensor.h"
84 #include "KX_RaySensor.h"
85 #include "KX_ArmatureSensor.h"
86 #include "KX_SceneActuator.h"
87 #include "KX_GameActuator.h"
88 #include "KX_ParentActuator.h"
89 #include "KX_SCA_DynamicActuator.h"
90 #include "KX_SteeringActuator.h"
91 #include "KX_NavMeshObject.h"
92
93 #include "SCA_IInputDevice.h"
94 #include "SCA_PropertySensor.h"
95 #include "SCA_RandomActuator.h"
96 #include "SCA_KeyboardSensor.h" /* IsPrintable, ToCharacter */
97 #include "SCA_PythonKeyboard.h"
98 #include "SCA_PythonMouse.h"
99 #include "KX_ConstraintActuator.h"
100 #include "KX_IpoActuator.h"
101 #include "KX_SoundActuator.h"
102 #include "KX_StateActuator.h"
103 #include "BL_ActionActuator.h"
104 #include "BL_ArmatureObject.h"
105 #include "RAS_IRasterizer.h"
106 #include "RAS_ICanvas.h"
107 #include "RAS_BucketManager.h"
108 #include "RAS_2DFilterManager.h"
109 #include "MT_Vector3.h"
110 #include "MT_Point3.h"
111 #include "ListValue.h"
112 #include "InputParser.h"
113 #include "KX_Scene.h"
114
115 #include "NG_NetworkScene.h" //Needed for sendMessage()
116
117 #include "BL_Shader.h"
118
119 #include "KX_PyMath.h"
120
121 #include "PyObjectPlus.h"
122
123 #include "KX_PythonInitTypes.h" 
124
125 /* we only need this to get a list of libraries from the main struct */
126 #include "DNA_ID.h"
127 #include "DNA_scene_types.h"
128
129 #include "PHY_IPhysicsEnvironment.h"
130 #include "BKE_main.h"
131 #include "BKE_utildefines.h"
132 #include "BKE_global.h"
133 #include "BLI_blenlib.h"
134 #include "GPU_material.h"
135 #include "MEM_guardedalloc.h"
136
137 /* for converting new scenes */
138 #include "KX_BlenderSceneConverter.h"
139 #include "KX_MeshProxy.h" /* for creating a new library of mesh objects */
140 extern "C" {
141         #include "BKE_idcode.h"
142 }
143
144 #include "NG_NetworkScene.h" //Needed for sendMessage()
145
146 // 'local' copy of canvas ptr, for window height/width python scripts
147
148 #ifdef WITH_PYTHON
149
150 static RAS_ICanvas* gp_Canvas = NULL;
151 static char gp_GamePythonPath[FILE_MAXDIR + FILE_MAXFILE] = "";
152 static char gp_GamePythonPathOrig[FILE_MAXDIR + FILE_MAXFILE] = ""; // not super happy about this, but we need to remember the first loaded file for the global/dict load save
153
154 static SCA_PythonKeyboard* gp_PythonKeyboard = NULL;
155 static SCA_PythonMouse* gp_PythonMouse = NULL;
156 #endif // WITH_PYTHON
157
158 static KX_Scene*        gp_KetsjiScene = NULL;
159 static KX_KetsjiEngine* gp_KetsjiEngine = NULL;
160 static RAS_IRasterizer* gp_Rasterizer = NULL;
161
162
163 void KX_SetActiveScene(class KX_Scene* scene)
164 {
165         gp_KetsjiScene = scene;
166 }
167
168 class KX_Scene* KX_GetActiveScene()
169 {
170         return gp_KetsjiScene;
171 }
172
173 class KX_KetsjiEngine* KX_GetActiveEngine()
174 {
175         return gp_KetsjiEngine;
176 }
177
178 /* why is this in python? */
179 void    KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color)
180 {
181         if (gp_Rasterizer)
182                 gp_Rasterizer->DrawDebugLine(from,to,color);
183 }
184
185 void    KX_RasterizerDrawDebugCircle(const MT_Vector3& center, const MT_Scalar radius, const MT_Vector3& color,
186                                                                          const MT_Vector3& normal, int nsector)
187 {
188         if (gp_Rasterizer)
189                 gp_Rasterizer->DrawDebugCircle(center, radius, color, normal, nsector);
190 }
191
192 #ifdef WITH_PYTHON
193
194 static PyObject *gp_OrigPythonSysPath= NULL;
195 static PyObject *gp_OrigPythonSysModules= NULL;
196
197 /* Macro for building the keyboard translation */
198 //#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyLong_FromSsize_t(SCA_IInputDevice::KX_##name))
199 #define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyLong_FromSsize_t(name)); Py_DECREF(item)
200 /* For the defines for types from logic bricks, we do stuff explicitly... */
201 #define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, item=PyLong_FromSsize_t(name2)); Py_DECREF(item)
202
203
204 // temporarily python stuff, will be put in another place later !
205 #include "KX_Python.h"
206 #include "SCA_PythonController.h"
207 // List of methods defined in the module
208
209 static PyObject* ErrorObject;
210 static const char *gPyGetRandomFloat_doc="getRandomFloat returns a random floating point value in the range [0..1]";
211
212 static PyObject* gPyGetRandomFloat(PyObject*)
213 {
214         return PyFloat_FromDouble(MT_random());
215 }
216
217 static PyObject* gPySetGravity(PyObject*, PyObject* value)
218 {
219         MT_Vector3 vec;
220         if (!PyVecTo(value, vec))
221                 return NULL;
222
223         if (gp_KetsjiScene)
224                 gp_KetsjiScene->SetGravity(vec);
225         
226         Py_RETURN_NONE;
227 }
228
229 static char gPyExpandPath_doc[] =
230 "(path) - Converts a blender internal path into a proper file system path.\n\
231 path - the string path to convert.\n\n\
232 Use / as directory separator in path\n\
233 You can use '//' at the start of the string to define a relative path;\n\
234 Blender replaces that string by the directory of the startup .blend or runtime\n\
235 file to make a full path name (doesn't change during the game, even if you load\n\
236 other .blend).\n\
237 The function also converts the directory separator to the local file system format.";
238
239 static PyObject* gPyExpandPath(PyObject*, PyObject* args)
240 {
241         char expanded[FILE_MAXDIR + FILE_MAXFILE];
242         char* filename;
243         
244         if (!PyArg_ParseTuple(args,"s:ExpandPath",&filename))
245                 return NULL;
246
247         BLI_strncpy(expanded, filename, FILE_MAXDIR + FILE_MAXFILE);
248         BLI_path_abs(expanded, gp_GamePythonPath);
249         return PyUnicode_DecodeFSDefault(expanded);
250 }
251
252 static char gPyStartGame_doc[] =
253 "startGame(blend)\n\
254 Loads the blend file";
255
256 static PyObject* gPyStartGame(PyObject*, PyObject* args)
257 {
258         char* blendfile;
259
260         if (!PyArg_ParseTuple(args, "s:startGame", &blendfile))
261                 return NULL;
262
263         gp_KetsjiEngine->RequestExit(KX_EXIT_REQUEST_START_OTHER_GAME);
264         gp_KetsjiEngine->SetNameNextGame(blendfile);
265
266         Py_RETURN_NONE;
267 }
268
269 static char gPyEndGame_doc[] =
270 "endGame()\n\
271 Ends the current game";
272
273 static PyObject* gPyEndGame(PyObject*)
274 {
275         gp_KetsjiEngine->RequestExit(KX_EXIT_REQUEST_QUIT_GAME);
276
277         //printf("%s\n", gp_GamePythonPath);
278
279         Py_RETURN_NONE;
280 }
281
282 static char gPyRestartGame_doc[] =
283 "restartGame()\n\
284 Restarts the current game by reloading the .blend file";
285
286 static PyObject* gPyRestartGame(PyObject*)
287 {
288         gp_KetsjiEngine->RequestExit(KX_EXIT_REQUEST_RESTART_GAME);
289         gp_KetsjiEngine->SetNameNextGame(gp_GamePythonPath);
290
291         Py_RETURN_NONE;
292 }
293
294 static char gPySaveGlobalDict_doc[] =
295         "saveGlobalDict()\n"
296         "Saves bge.logic.globalDict to a file";
297
298 static PyObject* gPySaveGlobalDict(PyObject*)
299 {
300         char marshal_path[512];
301         char *marshal_buffer = NULL;
302         unsigned int marshal_length;
303         FILE *fp = NULL;
304
305         pathGamePythonConfig(marshal_path);
306         marshal_length = saveGamePythonConfig(&marshal_buffer);
307
308         if (marshal_length && marshal_buffer)
309         {
310                 fp = fopen(marshal_path, "wb");
311
312                 if (fp)
313                 {
314                         if (fwrite(marshal_buffer, 1, marshal_length, fp) != marshal_length)
315                                 printf("Warning: could not write marshal data\n");
316
317                         fclose(fp);
318                 } else {
319                         printf("Warning: could not open marshal file\n");
320                 }
321         } else {
322                 printf("Warning: could not create marshal buffer\n");
323         }
324
325         if (marshal_buffer)
326                 delete [] marshal_buffer;
327
328         Py_RETURN_NONE;
329 }
330
331 static char gPyLoadGlobalDict_doc[] =
332         "LoadGlobalDict()\n"
333         "Loads bge.logic.globalDict from a file";
334
335 static PyObject* gPyLoadGlobalDict(PyObject*)
336 {
337         char marshal_path[512];
338         char *marshal_buffer = NULL;
339         unsigned int marshal_length;
340         FILE *fp = NULL;
341         int result;
342
343         pathGamePythonConfig(marshal_path);
344
345         fp = fopen(marshal_path, "rb");
346
347         if (fp) {
348                 // obtain file size:
349                 fseek (fp, 0, SEEK_END);
350                 marshal_length = ftell(fp);
351                 rewind(fp);
352
353                 marshal_buffer = (char*)malloc (sizeof(char)*marshal_length);
354
355                 result = fread(marshal_buffer, 1, marshal_length, fp);
356
357                 if (result == marshal_length) {
358                         loadGamePythonConfig(marshal_buffer, marshal_length);
359                 } else {
360                         printf("Warning: could not read all of '%s'\n", marshal_path);
361                 }
362
363                 free(marshal_buffer);
364                 fclose(fp);
365         } else {
366                 printf("Warning: could not open '%s'\n", marshal_path);
367         }
368
369         Py_RETURN_NONE;
370 }
371
372 static char gPySendMessage_doc[] = 
373 "sendMessage(subject, [body, to, from])\n\
374 sends a message in same manner as a message actuator\
375 subject = Subject of the message\
376 body = Message body\
377 to = Name of object to send the message to\
378 from = Name of object to send the string from";
379
380 static PyObject* gPySendMessage(PyObject*, PyObject* args)
381 {
382         char* subject;
383         char* body = (char *)"";
384         char* to = (char *)"";
385         char* from = (char *)"";
386
387         if (!PyArg_ParseTuple(args, "s|sss:sendMessage", &subject, &body, &to, &from))
388                 return NULL;
389
390         gp_KetsjiScene->GetNetworkScene()->SendMessage(to, from, subject, body);
391
392         Py_RETURN_NONE;
393 }
394
395 // this gets a pointer to an array filled with floats
396 static PyObject* gPyGetSpectrum(PyObject*)
397 {
398         PyObject* resultlist = PyList_New(512);
399
400         for (int index = 0; index < 512; index++)
401         {
402                 PyList_SET_ITEM(resultlist, index, PyFloat_FromDouble(0.0));
403         }
404
405         return resultlist;
406 }
407
408 static PyObject* gPySetLogicTicRate(PyObject*, PyObject* args)
409 {
410         float ticrate;
411         if (!PyArg_ParseTuple(args, "f:setLogicTicRate", &ticrate))
412                 return NULL;
413         
414         KX_KetsjiEngine::SetTicRate(ticrate);
415         Py_RETURN_NONE;
416 }
417
418 static PyObject* gPyGetLogicTicRate(PyObject*)
419 {
420         return PyFloat_FromDouble(KX_KetsjiEngine::GetTicRate());
421 }
422
423 static PyObject* gPySetMaxLogicFrame(PyObject*, PyObject* args)
424 {
425         int frame;
426         if (!PyArg_ParseTuple(args, "i:setMaxLogicFrame", &frame))
427                 return NULL;
428         
429         KX_KetsjiEngine::SetMaxLogicFrame(frame);
430         Py_RETURN_NONE;
431 }
432
433 static PyObject* gPyGetMaxLogicFrame(PyObject*)
434 {
435         return PyLong_FromSsize_t(KX_KetsjiEngine::GetMaxLogicFrame());
436 }
437
438 static PyObject* gPySetMaxPhysicsFrame(PyObject*, PyObject* args)
439 {
440         int frame;
441         if (!PyArg_ParseTuple(args, "i:setMaxPhysicsFrame", &frame))
442                 return NULL;
443         
444         KX_KetsjiEngine::SetMaxPhysicsFrame(frame);
445         Py_RETURN_NONE;
446 }
447
448 static PyObject* gPyGetMaxPhysicsFrame(PyObject*)
449 {
450         return PyLong_FromSsize_t(KX_KetsjiEngine::GetMaxPhysicsFrame());
451 }
452
453 static PyObject* gPySetPhysicsTicRate(PyObject*, PyObject* args)
454 {
455         float ticrate;
456         if (!PyArg_ParseTuple(args, "f:setPhysicsTicRate", &ticrate))
457                 return NULL;
458         
459         PHY_GetActiveEnvironment()->setFixedTimeStep(true,ticrate);
460         Py_RETURN_NONE;
461 }
462 #if 0 // unused
463 static PyObject* gPySetPhysicsDebug(PyObject*, PyObject* args)
464 {
465         int debugMode;
466         if (!PyArg_ParseTuple(args, "i:setPhysicsDebug", &debugMode))
467                 return NULL;
468         
469         PHY_GetActiveEnvironment()->setDebugMode(debugMode);
470         Py_RETURN_NONE;
471 }
472 #endif
473
474
475 static PyObject* gPyGetPhysicsTicRate(PyObject*)
476 {
477         return PyFloat_FromDouble(PHY_GetActiveEnvironment()->getFixedTimeStep());
478 }
479
480 static PyObject* gPyGetAverageFrameRate(PyObject*)
481 {
482         return PyFloat_FromDouble(KX_KetsjiEngine::GetAverageFrameRate());
483 }
484
485 static PyObject* gPyGetBlendFileList(PyObject*, PyObject* args)
486 {
487         char cpath[sizeof(gp_GamePythonPath)];
488         char *searchpath = NULL;
489         PyObject* list, *value;
490         
491     DIR *dp;
492     struct dirent *dirp;
493         
494         if (!PyArg_ParseTuple(args, "|s:getBlendFileList", &searchpath))
495                 return NULL;
496         
497         list = PyList_New(0);
498         
499         if (searchpath) {
500                 BLI_strncpy(cpath, searchpath, FILE_MAXDIR + FILE_MAXFILE);
501                 BLI_path_abs(cpath, gp_GamePythonPath);
502         } else {
503                 /* Get the dir only */
504                 BLI_split_dirfile(gp_GamePythonPath, cpath, NULL);
505         }
506         
507     if((dp  = opendir(cpath)) == NULL) {
508                 /* todo, show the errno, this shouldnt happen anyway if the blendfile is readable */
509                 fprintf(stderr, "Could not read directoty (%s) failed, code %d (%s)\n", cpath, errno, strerror(errno));
510                 return list;
511     }
512         
513     while ((dirp = readdir(dp)) != NULL) {
514                 if (BLI_testextensie(dirp->d_name, ".blend")) {
515                         value= PyUnicode_DecodeFSDefault(dirp->d_name);
516                         PyList_Append(list, value);
517                         Py_DECREF(value);
518                 }
519     }
520         
521     closedir(dp);
522     return list;
523 }
524
525 static char gPyAddScene_doc[] = 
526 "addScene(name, [overlay])\n\
527 adds a scene to the game engine\n\
528 name = Name of the scene\n\
529 overlay = Overlay or underlay";
530 static PyObject* gPyAddScene(PyObject*, PyObject* args)
531 {
532         char* name;
533         int overlay = 1;
534         
535         if (!PyArg_ParseTuple(args, "s|i:addScene", &name , &overlay))
536                 return NULL;
537         
538         gp_KetsjiEngine->ConvertAndAddScene(name, (overlay != 0));
539
540         Py_RETURN_NONE;
541 }
542
543 static const char *gPyGetCurrentScene_doc =
544 "getCurrentScene()\n"
545 "Gets a reference to the current scene.\n";
546 static PyObject* gPyGetCurrentScene(PyObject* self)
547 {
548         return gp_KetsjiScene->GetProxy();
549 }
550
551 static const char *gPyGetSceneList_doc =
552 "getSceneList()\n"
553 "Return a list of converted scenes.\n";
554 static PyObject* gPyGetSceneList(PyObject* self)
555 {
556         KX_KetsjiEngine* m_engine = KX_GetActiveEngine();
557         PyObject* list;
558         KX_SceneList* scenes = m_engine->CurrentScenes();
559         int numScenes = scenes->size();
560         int i;
561         
562         list = PyList_New(numScenes);
563         
564         for (i=0;i<numScenes;i++)
565         {
566                 KX_Scene* scene = scenes->at(i);
567                 PyList_SET_ITEM(list, i, scene->GetProxy());
568         }
569
570         return list;
571 }
572
573 static PyObject *pyPrintStats(PyObject *,PyObject *,PyObject *)
574 {
575         gp_KetsjiScene->GetSceneConverter()->PrintStats();
576         Py_RETURN_NONE;
577 }
578
579 static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *)
580 {
581 #define pprint(x) std::cout << x << std::endl;
582         bool count=0;
583         bool support=0;
584         pprint("Supported Extensions...");
585         pprint(" GL_ARB_shader_objects supported?       "<< (GLEW_ARB_shader_objects?"yes.":"no."));
586         count = 1;
587
588         support= GLEW_ARB_vertex_shader;
589         pprint(" GL_ARB_vertex_shader supported?        "<< (support?"yes.":"no."));
590         count = 1;
591         if(support){
592                 pprint(" ----------Details----------");
593                 int max=0;
594                 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, (GLint*)&max);
595                 pprint("  Max uniform components." << max);
596
597                 glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, (GLint*)&max);
598                 pprint("  Max varying floats." << max);
599
600                 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, (GLint*)&max);
601                 pprint("  Max vertex texture units." << max);
602         
603                 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, (GLint*)&max);
604                 pprint("  Max combined texture units." << max);
605                 pprint("");
606         }
607
608         support=GLEW_ARB_fragment_shader;
609         pprint(" GL_ARB_fragment_shader supported?      "<< (support?"yes.":"no."));
610         count = 1;
611         if(support){
612                 pprint(" ----------Details----------");
613                 int max=0;
614                 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, (GLint*)&max);
615                 pprint("  Max uniform components." << max);
616                 pprint("");
617         }
618
619         support = GLEW_ARB_texture_cube_map;
620         pprint(" GL_ARB_texture_cube_map supported?     "<< (support?"yes.":"no."));
621         count = 1;
622         if(support){
623                 pprint(" ----------Details----------");
624                 int size=0;
625                 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, (GLint*)&size);
626                 pprint("  Max cubemap size." << size);
627                 pprint("");
628         }
629
630         support = GLEW_ARB_multitexture;
631         count = 1;
632         pprint(" GL_ARB_multitexture supported?         "<< (support?"yes.":"no."));
633         if(support){
634                 pprint(" ----------Details----------");
635                 int units=0;
636                 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint*)&units);
637                 pprint("  Max texture units available.  " << units);
638                 pprint("");
639         }
640
641         pprint(" GL_ARB_texture_env_combine supported?  "<< (GLEW_ARB_texture_env_combine?"yes.":"no."));
642         count = 1;
643
644         if(!count)
645                 pprint("No extenstions are used in this build");
646
647         Py_RETURN_NONE;
648 }
649
650 static PyObject *gLibLoad(PyObject*, PyObject* args, PyObject* kwds)
651 {
652         KX_Scene *kx_scene= gp_KetsjiScene;
653         char *path;
654         char *group;
655         Py_buffer py_buffer;
656         py_buffer.buf = NULL;
657         char *err_str= NULL;
658
659         short options=0;
660         int load_actions=0, verbose=0;
661
662         static const char *kwlist[] = {"path", "group", "buffer", "load_actions", "verbose", NULL};
663         
664         if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|y*ii:LibLoad", const_cast<char**>(kwlist),
665                                                                         &path, &group, &py_buffer, &load_actions, &verbose))
666                 return NULL;
667
668         /* setup options */
669         if (load_actions != 0)
670                 options |= KX_BlenderSceneConverter::LIB_LOAD_LOAD_ACTIONS;
671         if (verbose != 0)
672                 options |= KX_BlenderSceneConverter::LIB_LOAD_VERBOSE;
673
674         if (!py_buffer.buf)
675         {
676                 char abs_path[FILE_MAX];
677                 // Make the path absolute
678                 BLI_strncpy(abs_path, path, sizeof(abs_path));
679                 BLI_path_abs(abs_path, gp_GamePythonPath);
680
681                 if(kx_scene->GetSceneConverter()->LinkBlendFilePath(abs_path, group, kx_scene, &err_str, options)) {
682                         Py_RETURN_TRUE;
683                 }
684         }
685         else
686         {
687
688                 if(kx_scene->GetSceneConverter()->LinkBlendFileMemory(py_buffer.buf, py_buffer.len, path, group, kx_scene, &err_str, options))  {
689                         PyBuffer_Release(&py_buffer);
690                         Py_RETURN_TRUE;
691                 }
692
693                 PyBuffer_Release(&py_buffer);
694         }
695         
696         if(err_str) {
697                 PyErr_SetString(PyExc_ValueError, err_str);
698                 return NULL;
699         }
700         
701         Py_RETURN_FALSE;
702 }
703
704 static PyObject *gLibNew(PyObject*, PyObject* args)
705 {
706         KX_Scene *kx_scene= gp_KetsjiScene;
707         char *path;
708         char *group;
709         char *name;
710         PyObject *names;
711         int idcode;
712
713         if (!PyArg_ParseTuple(args,"ssO!:LibNew",&path, &group, &PyList_Type, &names))
714                 return NULL;
715         
716         if(kx_scene->GetSceneConverter()->GetMainDynamicPath(path))
717         {
718                 PyErr_SetString(PyExc_KeyError, "the name of the path given exists");
719                 return NULL;
720         }
721         
722         idcode= BKE_idcode_from_name(group);
723         if(idcode==0) {
724                 PyErr_Format(PyExc_ValueError, "invalid group given \"%s\"", group);
725                 return NULL;
726         }
727         
728         Main *maggie= (Main *)MEM_callocN( sizeof(Main), "BgeMain");
729         kx_scene->GetSceneConverter()->GetMainDynamic().push_back(maggie);
730         strncpy(maggie->name, path, sizeof(maggie->name)-1);
731         
732         /* Copy the object into main */
733         if(idcode==ID_ME) {
734                 PyObject *ret= PyList_New(0);
735                 PyObject *item;
736                 for(int i= 0; i < PyList_GET_SIZE(names); i++) {
737                         name= _PyUnicode_AsString(PyList_GET_ITEM(names, i));
738                         if(name) {
739                                 RAS_MeshObject *meshobj= kx_scene->GetSceneConverter()->ConvertMeshSpecial(kx_scene, maggie, name);
740                                 if(meshobj) {
741                                         KX_MeshProxy* meshproxy = new KX_MeshProxy(meshobj);
742                                         item= meshproxy->NewProxy(true);
743                                         PyList_Append(ret, item);
744                                         Py_DECREF(item);
745                                 }
746                         }
747                         else {
748                                 PyErr_Clear(); /* wasnt a string, ignore for now */
749                         }
750                 }
751                 
752                 return ret;
753         }
754         else {
755                 PyErr_Format(PyExc_ValueError, "only \"Mesh\" group currently supported");
756                 return NULL;
757         }
758         
759         Py_RETURN_NONE;
760 }
761
762 static PyObject *gLibFree(PyObject*, PyObject* args)
763 {
764         KX_Scene *kx_scene= gp_KetsjiScene;
765         char *path;
766
767         if (!PyArg_ParseTuple(args,"s:LibFree",&path))
768                 return NULL;
769
770         if (kx_scene->GetSceneConverter()->FreeBlendFile(path))
771         {
772                 Py_RETURN_TRUE;
773         }
774         else {
775                 Py_RETURN_FALSE;
776         }
777 }
778
779 static PyObject *gLibList(PyObject*, PyObject* args)
780 {
781         vector<Main*> &dynMaggie = gp_KetsjiScene->GetSceneConverter()->GetMainDynamic();
782         int i= 0;
783         PyObject *list= PyList_New(dynMaggie.size());
784         
785         for (vector<Main*>::iterator it=dynMaggie.begin(); !(it==dynMaggie.end()); it++)
786         {
787                 PyList_SET_ITEM(list, i++, PyUnicode_FromString( (*it)->name) );
788         }
789         
790         return list;
791 }
792
793 static struct PyMethodDef game_methods[] = {
794         {"expandPath", (PyCFunction)gPyExpandPath, METH_VARARGS, (const char *)gPyExpandPath_doc},
795         {"startGame", (PyCFunction)gPyStartGame, METH_VARARGS, (const char *)gPyStartGame_doc},
796         {"endGame", (PyCFunction)gPyEndGame, METH_NOARGS, (const char *)gPyEndGame_doc},
797         {"restartGame", (PyCFunction)gPyRestartGame, METH_NOARGS, (const char *)gPyRestartGame_doc},
798         {"saveGlobalDict", (PyCFunction)gPySaveGlobalDict, METH_NOARGS, (const char *)gPySaveGlobalDict_doc},
799         {"loadGlobalDict", (PyCFunction)gPyLoadGlobalDict, METH_NOARGS, (const char *)gPyLoadGlobalDict_doc},
800         {"sendMessage", (PyCFunction)gPySendMessage, METH_VARARGS, (const char *)gPySendMessage_doc},
801         {"getCurrentController", (PyCFunction) SCA_PythonController::sPyGetCurrentController, METH_NOARGS, SCA_PythonController::sPyGetCurrentController__doc__},
802         {"getCurrentScene", (PyCFunction) gPyGetCurrentScene, METH_NOARGS, gPyGetCurrentScene_doc},
803         {"getSceneList", (PyCFunction) gPyGetSceneList, METH_NOARGS, (const char *)gPyGetSceneList_doc},
804         {"addScene", (PyCFunction)gPyAddScene, METH_VARARGS, (const char *)gPyAddScene_doc},
805         {"getRandomFloat",(PyCFunction) gPyGetRandomFloat, METH_NOARGS, (const char *)gPyGetRandomFloat_doc},
806         {"setGravity",(PyCFunction) gPySetGravity, METH_O, (const char *)"set Gravitation"},
807         {"getSpectrum",(PyCFunction) gPyGetSpectrum, METH_NOARGS, (const char *)"get audio spectrum"},
808         {"getMaxLogicFrame", (PyCFunction) gPyGetMaxLogicFrame, METH_NOARGS, (const char *)"Gets the max number of logic frame per render frame"},
809         {"setMaxLogicFrame", (PyCFunction) gPySetMaxLogicFrame, METH_VARARGS, (const char *)"Sets the max number of logic frame per render frame"},
810         {"getMaxPhysicsFrame", (PyCFunction) gPyGetMaxPhysicsFrame, METH_NOARGS, (const char *)"Gets the max number of physics frame per render frame"},
811         {"setMaxPhysicsFrame", (PyCFunction) gPySetMaxPhysicsFrame, METH_VARARGS, (const char *)"Sets the max number of physics farme per render frame"},
812         {"getLogicTicRate", (PyCFunction) gPyGetLogicTicRate, METH_NOARGS, (const char *)"Gets the logic tic rate"},
813         {"setLogicTicRate", (PyCFunction) gPySetLogicTicRate, METH_VARARGS, (const char *)"Sets the logic tic rate"},
814         {"getPhysicsTicRate", (PyCFunction) gPyGetPhysicsTicRate, METH_NOARGS, (const char *)"Gets the physics tic rate"},
815         {"setPhysicsTicRate", (PyCFunction) gPySetPhysicsTicRate, METH_VARARGS, (const char *)"Sets the physics tic rate"},
816         {"getAverageFrameRate", (PyCFunction) gPyGetAverageFrameRate, METH_NOARGS, (const char *)"Gets the estimated average frame rate"},
817         {"getBlendFileList", (PyCFunction)gPyGetBlendFileList, METH_VARARGS, (const char *)"Gets a list of blend files in the same directory as the current blend file"},
818         {"PrintGLInfo", (PyCFunction)pyPrintExt, METH_NOARGS, (const char *)"Prints GL Extension Info"},
819         {"PrintMemInfo", (PyCFunction)pyPrintStats, METH_NOARGS, (const char *)"Print engine stastics"},
820         
821         /* library functions */
822         {"LibLoad", (PyCFunction)gLibLoad, METH_VARARGS|METH_KEYWORDS, (const char *)""},
823         {"LibNew", (PyCFunction)gLibNew, METH_VARARGS, (const char *)""},
824         {"LibFree", (PyCFunction)gLibFree, METH_VARARGS, (const char *)""},
825         {"LibList", (PyCFunction)gLibList, METH_VARARGS, (const char *)""},
826         
827         {NULL, (PyCFunction) NULL, 0, NULL }
828 };
829
830 static PyObject* gPyGetWindowHeight(PyObject*, PyObject* args)
831 {
832         return PyLong_FromSsize_t((gp_Canvas ? gp_Canvas->GetHeight() : 0));
833 }
834
835
836
837 static PyObject* gPyGetWindowWidth(PyObject*, PyObject* args)
838 {
839         return PyLong_FromSsize_t((gp_Canvas ? gp_Canvas->GetWidth() : 0));
840 }
841
842
843
844 // temporarility visibility thing, will be moved to rasterizer/renderer later
845 bool gUseVisibilityTemp = false;
846
847 static PyObject* gPyEnableVisibility(PyObject*, PyObject* args)
848 {
849         int visible;
850         if (!PyArg_ParseTuple(args,"i:enableVisibility",&visible))
851                 return NULL;
852         
853         gUseVisibilityTemp = (visible != 0);
854         Py_RETURN_NONE;
855 }
856
857
858
859 static PyObject* gPyShowMouse(PyObject*, PyObject* args)
860 {
861         int visible;
862         if (!PyArg_ParseTuple(args,"i:showMouse",&visible))
863                 return NULL;
864         
865         if (visible)
866         {
867                 if (gp_Canvas)
868                         gp_Canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
869         } else
870         {
871                 if (gp_Canvas)
872                         gp_Canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
873         }
874         
875         Py_RETURN_NONE;
876 }
877
878
879
880 static PyObject* gPySetMousePosition(PyObject*, PyObject* args)
881 {
882         int x,y;
883         if (!PyArg_ParseTuple(args,"ii:setMousePosition",&x,&y))
884                 return NULL;
885         
886         if (gp_Canvas)
887                 gp_Canvas->SetMousePosition(x,y);
888         
889         Py_RETURN_NONE;
890 }
891
892 static PyObject* gPySetEyeSeparation(PyObject*, PyObject* args)
893 {
894         float sep;
895         if (!PyArg_ParseTuple(args, "f:setEyeSeparation", &sep))
896                 return NULL;
897
898         if (!gp_Rasterizer) {
899                 PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setEyeSeparation(float), Rasterizer not available");
900                 return NULL;
901         }
902         
903         gp_Rasterizer->SetEyeSeparation(sep);
904         
905         Py_RETURN_NONE;
906 }
907
908 static PyObject* gPyGetEyeSeparation(PyObject*)
909 {
910         if (!gp_Rasterizer) {
911                 PyErr_SetString(PyExc_RuntimeError, "Rasterizer.getEyeSeparation(), Rasterizer not available");
912                 return NULL;
913         }
914         
915         return PyFloat_FromDouble(gp_Rasterizer->GetEyeSeparation());
916 }
917
918 static PyObject* gPySetFocalLength(PyObject*, PyObject* args)
919 {
920         float focus;
921         if (!PyArg_ParseTuple(args, "f:setFocalLength", &focus))
922                 return NULL;
923         
924         if (!gp_Rasterizer) {
925                 PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setFocalLength(float), Rasterizer not available");
926                 return NULL;
927         }
928
929         gp_Rasterizer->SetFocalLength(focus);
930         
931         Py_RETURN_NONE;
932 }
933
934 static PyObject* gPyGetFocalLength(PyObject*, PyObject*, PyObject*)
935 {
936         if (!gp_Rasterizer) {
937                 PyErr_SetString(PyExc_RuntimeError, "Rasterizer.getFocalLength(), Rasterizer not available");
938                 return NULL;
939         }
940         
941         return PyFloat_FromDouble(gp_Rasterizer->GetFocalLength());
942         
943         Py_RETURN_NONE;
944 }
945
946 static PyObject* gPySetBackgroundColor(PyObject*, PyObject* value)
947 {
948         
949         MT_Vector4 vec;
950         if (!PyVecTo(value, vec))
951                 return NULL;
952         
953         if (gp_Canvas)
954         {
955                 gp_Rasterizer->SetBackColor((float)vec[0], (float)vec[1], (float)vec[2], (float)vec[3]);
956         }
957
958         KX_WorldInfo *wi = gp_KetsjiScene->GetWorldInfo();
959         if (wi->hasWorld())
960                 wi->setBackColor((float)vec[0], (float)vec[1], (float)vec[2]);
961
962         Py_RETURN_NONE;
963 }
964
965
966
967 static PyObject* gPySetMistColor(PyObject*, PyObject* value)
968 {
969         
970         MT_Vector3 vec;
971         if (!PyVecTo(value, vec))
972                 return NULL;
973         
974         if (!gp_Rasterizer) {
975                 PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setMistColor(color), Rasterizer not available");
976                 return NULL;
977         }       
978         gp_Rasterizer->SetFogColor((float)vec[0], (float)vec[1], (float)vec[2]);
979         
980         Py_RETURN_NONE;
981 }
982
983 static PyObject* gPyDisableMist(PyObject*)
984 {
985         
986         if (!gp_Rasterizer) {
987                 PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setMistColor(color), Rasterizer not available");
988                 return NULL;
989         }       
990         gp_Rasterizer->DisableFog();
991         
992         Py_RETURN_NONE;
993 }
994
995 static PyObject* gPySetMistStart(PyObject*, PyObject* args)
996 {
997
998         float miststart;
999         if (!PyArg_ParseTuple(args,"f:setMistStart",&miststart))
1000                 return NULL;
1001         
1002         if (!gp_Rasterizer) {
1003                 PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setMistStart(float), Rasterizer not available");
1004                 return NULL;
1005         }
1006         
1007         gp_Rasterizer->SetFogStart(miststart);
1008         
1009         Py_RETURN_NONE;
1010 }
1011
1012
1013
1014 static PyObject* gPySetMistEnd(PyObject*, PyObject* args)
1015 {
1016
1017         float mistend;
1018         if (!PyArg_ParseTuple(args,"f:setMistEnd",&mistend))
1019                 return NULL;
1020         
1021         if (!gp_Rasterizer) {
1022                 PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setMistEnd(float), Rasterizer not available");
1023                 return NULL;
1024         }
1025         
1026         gp_Rasterizer->SetFogEnd(mistend);
1027         
1028         Py_RETURN_NONE;
1029 }
1030
1031
1032 static PyObject* gPySetAmbientColor(PyObject*, PyObject* value)
1033 {
1034         
1035         MT_Vector3 vec;
1036         if (!PyVecTo(value, vec))
1037                 return NULL;
1038         
1039         if (!gp_Rasterizer) {
1040                 PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setAmbientColor(color), Rasterizer not available");
1041                 return NULL;
1042         }       
1043         gp_Rasterizer->SetAmbientColor((float)vec[0], (float)vec[1], (float)vec[2]);
1044         
1045         Py_RETURN_NONE;
1046 }
1047
1048
1049
1050
1051 static PyObject* gPyMakeScreenshot(PyObject*, PyObject* args)
1052 {
1053         char* filename;
1054         if (!PyArg_ParseTuple(args,"s:makeScreenshot",&filename))
1055                 return NULL;
1056         
1057         if (gp_Canvas)
1058         {
1059                 gp_Canvas->MakeScreenShot(filename);
1060         }
1061         
1062         Py_RETURN_NONE;
1063 }
1064
1065 static PyObject* gPyEnableMotionBlur(PyObject*, PyObject* args)
1066 {
1067         float motionblurvalue;
1068         if (!PyArg_ParseTuple(args,"f:enableMotionBlur",&motionblurvalue))
1069                 return NULL;
1070         
1071         if (!gp_Rasterizer) {
1072                 PyErr_SetString(PyExc_RuntimeError, "Rasterizer.enableMotionBlur(float), Rasterizer not available");
1073                 return NULL;
1074         }
1075         
1076         gp_Rasterizer->EnableMotionBlur(motionblurvalue);
1077         
1078         Py_RETURN_NONE;
1079 }
1080
1081 static PyObject* gPyDisableMotionBlur(PyObject*)
1082 {
1083         if (!gp_Rasterizer) {
1084                 PyErr_SetString(PyExc_RuntimeError, "Rasterizer.disableMotionBlur(), Rasterizer not available");
1085                 return NULL;
1086         }
1087         
1088         gp_Rasterizer->DisableMotionBlur();
1089         
1090         Py_RETURN_NONE;
1091 }
1092
1093 int getGLSLSettingFlag(char *setting)
1094 {
1095         if(strcmp(setting, "lights") == 0)
1096                 return GAME_GLSL_NO_LIGHTS;
1097         else if(strcmp(setting, "shaders") == 0)
1098                 return GAME_GLSL_NO_SHADERS;
1099         else if(strcmp(setting, "shadows") == 0)
1100                 return GAME_GLSL_NO_SHADOWS;
1101         else if(strcmp(setting, "ramps") == 0)
1102                 return GAME_GLSL_NO_RAMPS;
1103         else if(strcmp(setting, "nodes") == 0)
1104                 return GAME_GLSL_NO_NODES;
1105         else if(strcmp(setting, "extra_textures") == 0)
1106                 return GAME_GLSL_NO_EXTRA_TEX;
1107         else
1108                 return -1;
1109 }
1110
1111 static PyObject* gPySetGLSLMaterialSetting(PyObject*,
1112                                                                                         PyObject* args,
1113                                                                                         PyObject*)
1114 {
1115         GameData *gm= &(gp_KetsjiScene->GetBlenderScene()->gm);
1116         char *setting;
1117         int enable, flag, sceneflag;
1118
1119         if (!PyArg_ParseTuple(args,"si:setGLSLMaterialSetting",&setting,&enable))
1120                 return NULL;
1121         
1122         flag = getGLSLSettingFlag(setting);
1123         
1124         if  (flag==-1) {
1125                 PyErr_SetString(PyExc_ValueError, "Rasterizer.setGLSLMaterialSetting(string): glsl setting is not known");
1126                 return NULL;
1127         }
1128
1129         sceneflag= gm->flag;
1130         
1131         if (enable)
1132                 gm->flag &= ~flag;
1133         else
1134                 gm->flag |= flag;
1135
1136         /* display lists and GLSL materials need to be remade */
1137         if(sceneflag != gm->flag) {
1138                 GPU_materials_free();
1139                 if(gp_KetsjiEngine) {
1140                         KX_SceneList *scenes = gp_KetsjiEngine->CurrentScenes();
1141                         KX_SceneList::iterator it;
1142
1143                         for(it=scenes->begin(); it!=scenes->end(); it++)
1144                                 if((*it)->GetBucketManager()) {
1145                                         (*it)->GetBucketManager()->ReleaseDisplayLists();
1146                                         (*it)->GetBucketManager()->ReleaseMaterials();
1147                                 }
1148                 }
1149         }
1150
1151         Py_RETURN_NONE;
1152 }
1153
1154 static PyObject* gPyGetGLSLMaterialSetting(PyObject*, 
1155                                                                          PyObject* args, 
1156                                                                          PyObject*)
1157 {
1158         GameData *gm= &(gp_KetsjiScene->GetBlenderScene()->gm);
1159         char *setting;
1160         int enabled = 0, flag;
1161
1162         if (!PyArg_ParseTuple(args,"s:getGLSLMaterialSetting",&setting))
1163                 return NULL;
1164         
1165         flag = getGLSLSettingFlag(setting);
1166         
1167         if  (flag==-1) {
1168                 PyErr_SetString(PyExc_ValueError, "Rasterizer.getGLSLMaterialSetting(string): glsl setting is not known");
1169                 return NULL;
1170         }
1171
1172         enabled = ((gm->flag & flag) != 0);
1173         return PyLong_FromSsize_t(enabled);
1174 }
1175
1176 #define KX_TEXFACE_MATERIAL                             0
1177 #define KX_BLENDER_MULTITEX_MATERIAL    1
1178 #define KX_BLENDER_GLSL_MATERIAL                2
1179
1180 static PyObject* gPySetMaterialType(PyObject*,
1181                                                                         PyObject* args,
1182                                                                         PyObject*)
1183 {
1184         GameData *gm= &(gp_KetsjiScene->GetBlenderScene()->gm);
1185         int type;
1186
1187         if (!PyArg_ParseTuple(args,"i:setMaterialType",&type))
1188                 return NULL;
1189
1190         if(type == KX_BLENDER_GLSL_MATERIAL)
1191                 gm->matmode= GAME_MAT_GLSL;
1192         else if(type == KX_BLENDER_MULTITEX_MATERIAL)
1193                 gm->matmode= GAME_MAT_MULTITEX;
1194         else if(type == KX_TEXFACE_MATERIAL)
1195                 gm->matmode= GAME_MAT_TEXFACE;
1196         else {
1197                 PyErr_SetString(PyExc_ValueError, "Rasterizer.setMaterialType(int): material type is not known");
1198                 return NULL;
1199         }
1200
1201         Py_RETURN_NONE;
1202 }
1203
1204 static PyObject* gPyGetMaterialType(PyObject*)
1205 {
1206         GameData *gm= &(gp_KetsjiScene->GetBlenderScene()->gm);
1207         int flag;
1208
1209         if(gm->matmode == GAME_MAT_GLSL)
1210                 flag = KX_BLENDER_GLSL_MATERIAL;
1211         else if(gm->matmode == GAME_MAT_MULTITEX)
1212                 flag = KX_BLENDER_MULTITEX_MATERIAL;
1213         else
1214                 flag = KX_TEXFACE_MATERIAL;
1215         
1216         return PyLong_FromSsize_t(flag);
1217 }
1218
1219 static PyObject* gPyDrawLine(PyObject*, PyObject* args)
1220 {
1221         PyObject* ob_from;
1222         PyObject* ob_to;
1223         PyObject* ob_color;
1224
1225         if (!gp_Rasterizer) {
1226                 PyErr_SetString(PyExc_RuntimeError, "Rasterizer.drawLine(obFrom, obTo, color): Rasterizer not available");
1227                 return NULL;
1228         }
1229
1230         if (!PyArg_ParseTuple(args,"OOO:drawLine",&ob_from,&ob_to,&ob_color))
1231                 return NULL;
1232
1233         MT_Vector3 from;
1234         MT_Vector3 to;
1235         MT_Vector3 color;
1236         if (!PyVecTo(ob_from, from))
1237                 return NULL;
1238         if (!PyVecTo(ob_to, to))
1239                 return NULL;
1240         if (!PyVecTo(ob_color, color))
1241                 return NULL;
1242
1243         gp_Rasterizer->DrawDebugLine(from,to,color);
1244         
1245         Py_RETURN_NONE;
1246 }
1247
1248 static struct PyMethodDef rasterizer_methods[] = {
1249   {"getWindowWidth",(PyCFunction) gPyGetWindowWidth,
1250    METH_VARARGS, "getWindowWidth doc"},
1251    {"getWindowHeight",(PyCFunction) gPyGetWindowHeight,
1252    METH_VARARGS, "getWindowHeight doc"},
1253   {"makeScreenshot",(PyCFunction)gPyMakeScreenshot,
1254         METH_VARARGS, "make Screenshot doc"},
1255    {"enableVisibility",(PyCFunction) gPyEnableVisibility,
1256    METH_VARARGS, "enableVisibility doc"},
1257         {"showMouse",(PyCFunction) gPyShowMouse,
1258    METH_VARARGS, "showMouse(bool visible)"},
1259    {"setMousePosition",(PyCFunction) gPySetMousePosition,
1260    METH_VARARGS, "setMousePosition(int x,int y)"},
1261   {"setBackgroundColor",(PyCFunction)gPySetBackgroundColor,METH_O,"set Background Color (rgb)"},
1262         {"setAmbientColor",(PyCFunction)gPySetAmbientColor,METH_O,"set Ambient Color (rgb)"},
1263  {"disableMist",(PyCFunction)gPyDisableMist,METH_NOARGS,"turn off mist"},
1264  {"setMistColor",(PyCFunction)gPySetMistColor,METH_O,"set Mist Color (rgb)"},
1265   {"setMistStart",(PyCFunction)gPySetMistStart,METH_VARARGS,"set Mist Start(rgb)"},
1266   {"setMistEnd",(PyCFunction)gPySetMistEnd,METH_VARARGS,"set Mist End(rgb)"},
1267   {"enableMotionBlur",(PyCFunction)gPyEnableMotionBlur,METH_VARARGS,"enable motion blur"},
1268   {"disableMotionBlur",(PyCFunction)gPyDisableMotionBlur,METH_NOARGS,"disable motion blur"},
1269
1270   
1271   {"setEyeSeparation", (PyCFunction) gPySetEyeSeparation, METH_VARARGS, "set the eye separation for stereo mode"},
1272   {"getEyeSeparation", (PyCFunction) gPyGetEyeSeparation, METH_NOARGS, "get the eye separation for stereo mode"},
1273   {"setFocalLength", (PyCFunction) gPySetFocalLength, METH_VARARGS, "set the focal length for stereo mode"},
1274   {"getFocalLength", (PyCFunction) gPyGetFocalLength, METH_VARARGS, "get the focal length for stereo mode"},
1275   {"setMaterialMode",(PyCFunction) gPySetMaterialType,
1276    METH_VARARGS, "set the material mode to use for OpenGL rendering"},
1277   {"getMaterialMode",(PyCFunction) gPyGetMaterialType,
1278    METH_NOARGS, "get the material mode being used for OpenGL rendering"},
1279   {"setGLSLMaterialSetting",(PyCFunction) gPySetGLSLMaterialSetting,
1280    METH_VARARGS, "set the state of a GLSL material setting"},
1281   {"getGLSLMaterialSetting",(PyCFunction) gPyGetGLSLMaterialSetting,
1282    METH_VARARGS, "get the state of a GLSL material setting"},
1283   {"drawLine", (PyCFunction) gPyDrawLine,
1284    METH_VARARGS, "draw a line on the screen"},
1285   { NULL, (PyCFunction) NULL, 0, NULL }
1286 };
1287
1288 // Initialization function for the module (*must* be called initGameLogic)
1289
1290 static char GameLogic_module_documentation[] =
1291 "This is the Python API for the game engine of bge.logic"
1292 ;
1293
1294 static char Rasterizer_module_documentation[] =
1295 "This is the Python API for the game engine of Rasterizer"
1296 ;
1297
1298 static struct PyModuleDef GameLogic_module_def = {
1299         {}, /* m_base */
1300         "GameLogic",  /* m_name */
1301         GameLogic_module_documentation,  /* m_doc */
1302         0,  /* m_size */
1303         game_methods,  /* m_methods */
1304         0,  /* m_reload */
1305         0,  /* m_traverse */
1306         0,  /* m_clear */
1307         0,  /* m_free */
1308 };
1309
1310 PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack to get gravity hook
1311 {
1312         PyObject* m;
1313         PyObject* d;
1314         PyObject* item; /* temp PyObject* storage */
1315         
1316         gp_KetsjiEngine = engine;
1317         gp_KetsjiScene = scene;
1318
1319         gUseVisibilityTemp=false;
1320         
1321         PyObjectPlus::ClearDeprecationWarning(); /* Not that nice to call here but makes sure warnings are reset between loading scenes */
1322         
1323         /* Use existing module where possible
1324          * be careful not to init any runtime vars after this */
1325         m = PyImport_ImportModule( "GameLogic" );
1326         if(m) {
1327                 Py_DECREF(m);
1328                 return m;
1329         }
1330         else {
1331                 PyErr_Clear();
1332                 // Create the module and add the functions      
1333                 m = PyModule_Create(&GameLogic_module_def);
1334                 PyDict_SetItemString(PySys_GetObject("modules"), GameLogic_module_def.m_name, m);
1335         }
1336         
1337         // Add some symbolic constants to the module
1338         d = PyModule_GetDict(m);
1339         
1340         // can be overwritten later for gameEngine instances that can load new blend files and re-initialize this module
1341         // for now its safe to make sure it exists for other areas such as the web plugin
1342         
1343         PyDict_SetItemString(d, "globalDict", item=PyDict_New()); Py_DECREF(item);
1344
1345         // Add keyboard and mouse attributes to this module
1346         MT_assert(!gp_PythonKeyboard);
1347         gp_PythonKeyboard = new SCA_PythonKeyboard(gp_KetsjiEngine->GetKeyboardDevice());
1348         PyDict_SetItemString(d, "keyboard", gp_PythonKeyboard->NewProxy(true));
1349
1350         MT_assert(!gp_PythonMouse);
1351         gp_PythonMouse = new SCA_PythonMouse(gp_KetsjiEngine->GetMouseDevice(), gp_Canvas);
1352         PyDict_SetItemString(d, "mouse", gp_PythonMouse->NewProxy(true));
1353
1354         ErrorObject = PyUnicode_FromString("GameLogic.error");
1355         PyDict_SetItemString(d, "error", ErrorObject);
1356         Py_DECREF(ErrorObject);
1357         
1358         // XXXX Add constants here
1359         /* To use logic bricks, we need some sort of constants. Here, we associate */
1360         /* constants and sumbolic names. Add them to dictionary d.                 */
1361
1362         /* 1. true and false: needed for everyone                                  */
1363         KX_MACRO_addTypesToDict(d, KX_TRUE,  SCA_ILogicBrick::KX_TRUE);
1364         KX_MACRO_addTypesToDict(d, KX_FALSE, SCA_ILogicBrick::KX_FALSE);
1365
1366         /* 2. Property sensor                                                      */
1367         KX_MACRO_addTypesToDict(d, KX_PROPSENSOR_EQUAL,      SCA_PropertySensor::KX_PROPSENSOR_EQUAL);
1368         KX_MACRO_addTypesToDict(d, KX_PROPSENSOR_NOTEQUAL,   SCA_PropertySensor::KX_PROPSENSOR_NOTEQUAL);
1369         KX_MACRO_addTypesToDict(d, KX_PROPSENSOR_INTERVAL,   SCA_PropertySensor::KX_PROPSENSOR_INTERVAL);
1370         KX_MACRO_addTypesToDict(d, KX_PROPSENSOR_CHANGED,    SCA_PropertySensor::KX_PROPSENSOR_CHANGED);
1371         KX_MACRO_addTypesToDict(d, KX_PROPSENSOR_EXPRESSION, SCA_PropertySensor::KX_PROPSENSOR_EXPRESSION);
1372
1373         /* 3. Constraint actuator                                                  */
1374         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_LOCX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCX);
1375         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_LOCY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCY);
1376         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_LOCZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCZ);
1377         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ROTX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTX);
1378         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ROTY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTY);
1379         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ROTZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTZ);
1380         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DIRPX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPX);
1381         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DIRPY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPY);
1382         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DIRPZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPZ);
1383         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DIRNX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNX);
1384         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DIRNY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNY);
1385         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DIRNZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNZ);
1386         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ORIX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIX);
1387         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ORIY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIY);
1388         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ORIZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIZ);
1389         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_FHPX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPX);
1390         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_FHPY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPY);
1391         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_FHPZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPZ);
1392         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_FHNX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNX);
1393         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_FHNY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNY);
1394         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_FHNZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNZ);
1395         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_NORMAL, KX_ConstraintActuator::KX_ACT_CONSTRAINT_NORMAL);
1396         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_MATERIAL, KX_ConstraintActuator::KX_ACT_CONSTRAINT_MATERIAL);
1397         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_PERMANENT, KX_ConstraintActuator::KX_ACT_CONSTRAINT_PERMANENT);
1398         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DISTANCE, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DISTANCE);
1399         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_LOCAL, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCAL);
1400         KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DOROTFH, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DOROTFH);
1401
1402         /* 4. Ipo actuator, simple part                                            */
1403         KX_MACRO_addTypesToDict(d, KX_IPOACT_PLAY,     KX_IpoActuator::KX_ACT_IPO_PLAY);
1404         KX_MACRO_addTypesToDict(d, KX_IPOACT_PINGPONG, KX_IpoActuator::KX_ACT_IPO_PINGPONG);
1405         KX_MACRO_addTypesToDict(d, KX_IPOACT_FLIPPER,  KX_IpoActuator::KX_ACT_IPO_FLIPPER);
1406         KX_MACRO_addTypesToDict(d, KX_IPOACT_LOOPSTOP, KX_IpoActuator::KX_ACT_IPO_LOOPSTOP);
1407         KX_MACRO_addTypesToDict(d, KX_IPOACT_LOOPEND,  KX_IpoActuator::KX_ACT_IPO_LOOPEND);
1408         KX_MACRO_addTypesToDict(d, KX_IPOACT_FROM_PROP,KX_IpoActuator::KX_ACT_IPO_FROM_PROP);
1409
1410         /* 5. Random distribution types                                            */
1411         KX_MACRO_addTypesToDict(d, KX_RANDOMACT_BOOL_CONST,      SCA_RandomActuator::KX_RANDOMACT_BOOL_CONST);
1412         KX_MACRO_addTypesToDict(d, KX_RANDOMACT_BOOL_UNIFORM,    SCA_RandomActuator::KX_RANDOMACT_BOOL_UNIFORM);
1413         KX_MACRO_addTypesToDict(d, KX_RANDOMACT_BOOL_BERNOUILLI, SCA_RandomActuator::KX_RANDOMACT_BOOL_BERNOUILLI);
1414         KX_MACRO_addTypesToDict(d, KX_RANDOMACT_INT_CONST,       SCA_RandomActuator::KX_RANDOMACT_INT_CONST);
1415         KX_MACRO_addTypesToDict(d, KX_RANDOMACT_INT_UNIFORM,     SCA_RandomActuator::KX_RANDOMACT_INT_UNIFORM);
1416         KX_MACRO_addTypesToDict(d, KX_RANDOMACT_INT_POISSON,     SCA_RandomActuator::KX_RANDOMACT_INT_POISSON);
1417         KX_MACRO_addTypesToDict(d, KX_RANDOMACT_FLOAT_CONST,     SCA_RandomActuator::KX_RANDOMACT_FLOAT_CONST);
1418         KX_MACRO_addTypesToDict(d, KX_RANDOMACT_FLOAT_UNIFORM,   SCA_RandomActuator::KX_RANDOMACT_FLOAT_UNIFORM);
1419         KX_MACRO_addTypesToDict(d, KX_RANDOMACT_FLOAT_NORMAL,    SCA_RandomActuator::KX_RANDOMACT_FLOAT_NORMAL);
1420         KX_MACRO_addTypesToDict(d, KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL, SCA_RandomActuator::KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL);
1421
1422         /* 6. Sound actuator                                                      */
1423         KX_MACRO_addTypesToDict(d, KX_SOUNDACT_PLAYSTOP,              KX_SoundActuator::KX_SOUNDACT_PLAYSTOP);
1424         KX_MACRO_addTypesToDict(d, KX_SOUNDACT_PLAYEND,               KX_SoundActuator::KX_SOUNDACT_PLAYEND);
1425         KX_MACRO_addTypesToDict(d, KX_SOUNDACT_LOOPSTOP,              KX_SoundActuator::KX_SOUNDACT_LOOPSTOP);
1426         KX_MACRO_addTypesToDict(d, KX_SOUNDACT_LOOPEND,               KX_SoundActuator::KX_SOUNDACT_LOOPEND);
1427         KX_MACRO_addTypesToDict(d, KX_SOUNDACT_LOOPBIDIRECTIONAL,     KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL);
1428         KX_MACRO_addTypesToDict(d, KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP,     KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP);
1429
1430         /* 7. Action actuator                                                                                                      */
1431         KX_MACRO_addTypesToDict(d, KX_ACTIONACT_PLAY,        ACT_ACTION_PLAY);
1432         KX_MACRO_addTypesToDict(d, KX_ACTIONACT_PINGPONG,    ACT_ACTION_PINGPONG);
1433         KX_MACRO_addTypesToDict(d, KX_ACTIONACT_FLIPPER,     ACT_ACTION_FLIPPER);
1434         KX_MACRO_addTypesToDict(d, KX_ACTIONACT_LOOPSTOP,    ACT_ACTION_LOOP_STOP);
1435         KX_MACRO_addTypesToDict(d, KX_ACTIONACT_LOOPEND,     ACT_ACTION_LOOP_END);
1436         KX_MACRO_addTypesToDict(d, KX_ACTIONACT_PROPERTY,    ACT_ACTION_FROM_PROP);
1437         
1438         /*8. GL_BlendFunc */
1439         KX_MACRO_addTypesToDict(d, BL_ZERO, GL_ZERO);
1440         KX_MACRO_addTypesToDict(d, BL_ONE, GL_ONE);
1441         KX_MACRO_addTypesToDict(d, BL_SRC_COLOR, GL_SRC_COLOR);
1442         KX_MACRO_addTypesToDict(d, BL_ONE_MINUS_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);
1443         KX_MACRO_addTypesToDict(d, BL_DST_COLOR, GL_DST_COLOR);
1444         KX_MACRO_addTypesToDict(d, BL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_DST_COLOR);
1445         KX_MACRO_addTypesToDict(d, BL_SRC_ALPHA, GL_SRC_ALPHA);
1446         KX_MACRO_addTypesToDict(d, BL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1447         KX_MACRO_addTypesToDict(d, BL_DST_ALPHA, GL_DST_ALPHA);
1448         KX_MACRO_addTypesToDict(d, BL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
1449         KX_MACRO_addTypesToDict(d, BL_SRC_ALPHA_SATURATE, GL_SRC_ALPHA_SATURATE);
1450
1451
1452         /* 9. UniformTypes */
1453         KX_MACRO_addTypesToDict(d, SHD_TANGENT, BL_Shader::SHD_TANGENT);
1454         KX_MACRO_addTypesToDict(d, MODELVIEWMATRIX, BL_Shader::MODELVIEWMATRIX);
1455         KX_MACRO_addTypesToDict(d, MODELVIEWMATRIX_TRANSPOSE, BL_Shader::MODELVIEWMATRIX_TRANSPOSE);
1456         KX_MACRO_addTypesToDict(d, MODELVIEWMATRIX_INVERSE, BL_Shader::MODELVIEWMATRIX_INVERSE);
1457         KX_MACRO_addTypesToDict(d, MODELVIEWMATRIX_INVERSETRANSPOSE, BL_Shader::MODELVIEWMATRIX_INVERSETRANSPOSE);
1458         KX_MACRO_addTypesToDict(d, MODELMATRIX, BL_Shader::MODELMATRIX);
1459         KX_MACRO_addTypesToDict(d, MODELMATRIX_TRANSPOSE, BL_Shader::MODELMATRIX_TRANSPOSE);
1460         KX_MACRO_addTypesToDict(d, MODELMATRIX_INVERSE, BL_Shader::MODELMATRIX_INVERSE);
1461         KX_MACRO_addTypesToDict(d, MODELMATRIX_INVERSETRANSPOSE, BL_Shader::MODELMATRIX_INVERSETRANSPOSE);
1462         KX_MACRO_addTypesToDict(d, VIEWMATRIX, BL_Shader::VIEWMATRIX);
1463         KX_MACRO_addTypesToDict(d, VIEWMATRIX_TRANSPOSE, BL_Shader::VIEWMATRIX_TRANSPOSE);
1464         KX_MACRO_addTypesToDict(d, VIEWMATRIX_INVERSE, BL_Shader::VIEWMATRIX_INVERSE);
1465         KX_MACRO_addTypesToDict(d, VIEWMATRIX_INVERSETRANSPOSE, BL_Shader::VIEWMATRIX_INVERSETRANSPOSE);
1466         KX_MACRO_addTypesToDict(d, CAM_POS, BL_Shader::CAM_POS);
1467         KX_MACRO_addTypesToDict(d, CONSTANT_TIMER, BL_Shader::CONSTANT_TIMER);
1468
1469         /* 10 state actuator */
1470         KX_MACRO_addTypesToDict(d, KX_STATE1, (1<<0));
1471         KX_MACRO_addTypesToDict(d, KX_STATE2, (1<<1));
1472         KX_MACRO_addTypesToDict(d, KX_STATE3, (1<<2));
1473         KX_MACRO_addTypesToDict(d, KX_STATE4, (1<<3));
1474         KX_MACRO_addTypesToDict(d, KX_STATE5, (1<<4));
1475         KX_MACRO_addTypesToDict(d, KX_STATE6, (1<<5));
1476         KX_MACRO_addTypesToDict(d, KX_STATE7, (1<<6));
1477         KX_MACRO_addTypesToDict(d, KX_STATE8, (1<<7));
1478         KX_MACRO_addTypesToDict(d, KX_STATE9, (1<<8));
1479         KX_MACRO_addTypesToDict(d, KX_STATE10, (1<<9));
1480         KX_MACRO_addTypesToDict(d, KX_STATE11, (1<<10));
1481         KX_MACRO_addTypesToDict(d, KX_STATE12, (1<<11));
1482         KX_MACRO_addTypesToDict(d, KX_STATE13, (1<<12));
1483         KX_MACRO_addTypesToDict(d, KX_STATE14, (1<<13));
1484         KX_MACRO_addTypesToDict(d, KX_STATE15, (1<<14));
1485         KX_MACRO_addTypesToDict(d, KX_STATE16, (1<<15));
1486         KX_MACRO_addTypesToDict(d, KX_STATE17, (1<<16));
1487         KX_MACRO_addTypesToDict(d, KX_STATE18, (1<<17));
1488         KX_MACRO_addTypesToDict(d, KX_STATE19, (1<<18));
1489         KX_MACRO_addTypesToDict(d, KX_STATE20, (1<<19));
1490         KX_MACRO_addTypesToDict(d, KX_STATE21, (1<<20));
1491         KX_MACRO_addTypesToDict(d, KX_STATE22, (1<<21));
1492         KX_MACRO_addTypesToDict(d, KX_STATE23, (1<<22));
1493         KX_MACRO_addTypesToDict(d, KX_STATE24, (1<<23));
1494         KX_MACRO_addTypesToDict(d, KX_STATE25, (1<<24));
1495         KX_MACRO_addTypesToDict(d, KX_STATE26, (1<<25));
1496         KX_MACRO_addTypesToDict(d, KX_STATE27, (1<<26));
1497         KX_MACRO_addTypesToDict(d, KX_STATE28, (1<<27));
1498         KX_MACRO_addTypesToDict(d, KX_STATE29, (1<<28));
1499         KX_MACRO_addTypesToDict(d, KX_STATE30, (1<<29));
1500         
1501         /* All Sensors */
1502         KX_MACRO_addTypesToDict(d, KX_SENSOR_JUST_ACTIVATED, SCA_ISensor::KX_SENSOR_JUST_ACTIVATED);
1503         KX_MACRO_addTypesToDict(d, KX_SENSOR_ACTIVE, SCA_ISensor::KX_SENSOR_ACTIVE);
1504         KX_MACRO_addTypesToDict(d, KX_SENSOR_JUST_DEACTIVATED, SCA_ISensor::KX_SENSOR_JUST_DEACTIVATED);
1505         KX_MACRO_addTypesToDict(d, KX_SENSOR_INACTIVE, SCA_ISensor::KX_SENSOR_INACTIVE);
1506         
1507         /* Radar Sensor */
1508         KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_POS_X, KX_RadarSensor::KX_RADAR_AXIS_POS_X);
1509         KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_POS_Y, KX_RadarSensor::KX_RADAR_AXIS_POS_Y);
1510         KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_POS_Z, KX_RadarSensor::KX_RADAR_AXIS_POS_Z);
1511         KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_NEG_X, KX_RadarSensor::KX_RADAR_AXIS_NEG_Y);
1512         KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_NEG_Y, KX_RadarSensor::KX_RADAR_AXIS_NEG_X);
1513         KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_NEG_Z, KX_RadarSensor::KX_RADAR_AXIS_NEG_Z);
1514
1515         /* Ray Sensor */
1516         KX_MACRO_addTypesToDict(d, KX_RAY_AXIS_POS_X, KX_RaySensor::KX_RAY_AXIS_POS_X);
1517         KX_MACRO_addTypesToDict(d, KX_RAY_AXIS_POS_Y, KX_RaySensor::KX_RAY_AXIS_POS_Y);
1518         KX_MACRO_addTypesToDict(d, KX_RAY_AXIS_POS_Z, KX_RaySensor::KX_RAY_AXIS_POS_Z);
1519         KX_MACRO_addTypesToDict(d, KX_RAY_AXIS_NEG_X, KX_RaySensor::KX_RAY_AXIS_NEG_Y);
1520         KX_MACRO_addTypesToDict(d, KX_RAY_AXIS_NEG_Y, KX_RaySensor::KX_RAY_AXIS_NEG_X);
1521         KX_MACRO_addTypesToDict(d, KX_RAY_AXIS_NEG_Z, KX_RaySensor::KX_RAY_AXIS_NEG_Z);
1522
1523         /* Dynamic actuator */
1524         KX_MACRO_addTypesToDict(d, KX_DYN_RESTORE_DYNAMICS, KX_SCA_DynamicActuator::KX_DYN_RESTORE_DYNAMICS);
1525         KX_MACRO_addTypesToDict(d, KX_DYN_DISABLE_DYNAMICS, KX_SCA_DynamicActuator::KX_DYN_DISABLE_DYNAMICS);
1526         KX_MACRO_addTypesToDict(d, KX_DYN_ENABLE_RIGID_BODY, KX_SCA_DynamicActuator::KX_DYN_ENABLE_RIGID_BODY);
1527         KX_MACRO_addTypesToDict(d, KX_DYN_DISABLE_RIGID_BODY, KX_SCA_DynamicActuator::KX_DYN_DISABLE_RIGID_BODY);
1528         KX_MACRO_addTypesToDict(d, KX_DYN_SET_MASS, KX_SCA_DynamicActuator::KX_DYN_SET_MASS);
1529
1530         /* Input & Mouse Sensor */
1531         KX_MACRO_addTypesToDict(d, KX_INPUT_NONE, SCA_InputEvent::KX_NO_INPUTSTATUS);
1532         KX_MACRO_addTypesToDict(d, KX_INPUT_JUST_ACTIVATED, SCA_InputEvent::KX_JUSTACTIVATED);
1533         KX_MACRO_addTypesToDict(d, KX_INPUT_ACTIVE, SCA_InputEvent::KX_ACTIVE);
1534         KX_MACRO_addTypesToDict(d, KX_INPUT_JUST_RELEASED, SCA_InputEvent::KX_JUSTRELEASED);
1535         
1536         KX_MACRO_addTypesToDict(d, KX_MOUSE_BUT_LEFT, SCA_IInputDevice::KX_LEFTMOUSE);
1537         KX_MACRO_addTypesToDict(d, KX_MOUSE_BUT_MIDDLE, SCA_IInputDevice::KX_MIDDLEMOUSE);
1538         KX_MACRO_addTypesToDict(d, KX_MOUSE_BUT_RIGHT, SCA_IInputDevice::KX_RIGHTMOUSE);
1539
1540         /* 2D Filter Actuator */
1541         KX_MACRO_addTypesToDict(d, RAS_2DFILTER_ENABLED, RAS_2DFilterManager::RAS_2DFILTER_ENABLED);
1542         KX_MACRO_addTypesToDict(d, RAS_2DFILTER_DISABLED, RAS_2DFilterManager::RAS_2DFILTER_DISABLED);
1543         KX_MACRO_addTypesToDict(d, RAS_2DFILTER_NOFILTER, RAS_2DFilterManager::RAS_2DFILTER_NOFILTER);
1544         KX_MACRO_addTypesToDict(d, RAS_2DFILTER_MOTIONBLUR, RAS_2DFilterManager::RAS_2DFILTER_MOTIONBLUR);
1545         KX_MACRO_addTypesToDict(d, RAS_2DFILTER_BLUR, RAS_2DFilterManager::RAS_2DFILTER_BLUR);
1546         KX_MACRO_addTypesToDict(d, RAS_2DFILTER_SHARPEN, RAS_2DFilterManager::RAS_2DFILTER_SHARPEN);
1547         KX_MACRO_addTypesToDict(d, RAS_2DFILTER_DILATION, RAS_2DFilterManager::RAS_2DFILTER_DILATION);
1548         KX_MACRO_addTypesToDict(d, RAS_2DFILTER_EROSION, RAS_2DFilterManager::RAS_2DFILTER_EROSION);
1549         KX_MACRO_addTypesToDict(d, RAS_2DFILTER_LAPLACIAN, RAS_2DFilterManager::RAS_2DFILTER_LAPLACIAN);
1550         KX_MACRO_addTypesToDict(d, RAS_2DFILTER_SOBEL, RAS_2DFilterManager::RAS_2DFILTER_SOBEL);
1551         KX_MACRO_addTypesToDict(d, RAS_2DFILTER_PREWITT, RAS_2DFilterManager::RAS_2DFILTER_PREWITT);
1552         KX_MACRO_addTypesToDict(d, RAS_2DFILTER_GRAYSCALE, RAS_2DFilterManager::RAS_2DFILTER_GRAYSCALE);
1553         KX_MACRO_addTypesToDict(d, RAS_2DFILTER_SEPIA, RAS_2DFilterManager::RAS_2DFILTER_SEPIA);
1554         KX_MACRO_addTypesToDict(d, RAS_2DFILTER_INVERT, RAS_2DFilterManager::RAS_2DFILTER_INVERT);
1555         KX_MACRO_addTypesToDict(d, RAS_2DFILTER_CUSTOMFILTER, RAS_2DFilterManager::RAS_2DFILTER_CUSTOMFILTER);
1556
1557         /* Sound Actuator */
1558         KX_MACRO_addTypesToDict(d, KX_SOUNDACT_PLAYSTOP, KX_SoundActuator::KX_SOUNDACT_PLAYSTOP);
1559         KX_MACRO_addTypesToDict(d, KX_SOUNDACT_PLAYEND, KX_SoundActuator::KX_SOUNDACT_PLAYEND);
1560         KX_MACRO_addTypesToDict(d, KX_SOUNDACT_LOOPSTOP, KX_SoundActuator::KX_SOUNDACT_LOOPSTOP);
1561         KX_MACRO_addTypesToDict(d, KX_SOUNDACT_LOOPEND, KX_SoundActuator:: KX_SOUNDACT_LOOPEND);
1562         KX_MACRO_addTypesToDict(d, KX_SOUNDACT_LOOPBIDIRECTIONAL, KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL);
1563         KX_MACRO_addTypesToDict(d, KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP, KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP);
1564
1565         /* State Actuator */
1566         KX_MACRO_addTypesToDict(d, KX_STATE_OP_CPY, KX_StateActuator::OP_CPY);
1567         KX_MACRO_addTypesToDict(d, KX_STATE_OP_SET, KX_StateActuator::OP_SET);
1568         KX_MACRO_addTypesToDict(d, KX_STATE_OP_CLR, KX_StateActuator::OP_CLR);
1569         KX_MACRO_addTypesToDict(d, KX_STATE_OP_NEG, KX_StateActuator::OP_NEG);
1570
1571         /* Game Actuator Modes */
1572         KX_MACRO_addTypesToDict(d, KX_GAME_LOAD, KX_GameActuator::KX_GAME_LOAD);
1573         KX_MACRO_addTypesToDict(d, KX_GAME_START, KX_GameActuator::KX_GAME_START);
1574         KX_MACRO_addTypesToDict(d, KX_GAME_RESTART, KX_GameActuator::KX_GAME_RESTART);
1575         KX_MACRO_addTypesToDict(d, KX_GAME_QUIT, KX_GameActuator::KX_GAME_QUIT);
1576         KX_MACRO_addTypesToDict(d, KX_GAME_SAVECFG, KX_GameActuator::KX_GAME_SAVECFG);
1577         KX_MACRO_addTypesToDict(d, KX_GAME_LOADCFG, KX_GameActuator::KX_GAME_LOADCFG);
1578
1579         /* Scene Actuator Modes */
1580         KX_MACRO_addTypesToDict(d, KX_SCENE_RESTART, KX_SceneActuator::KX_SCENE_RESTART);
1581         KX_MACRO_addTypesToDict(d, KX_SCENE_SET_SCENE, KX_SceneActuator::KX_SCENE_SET_SCENE);
1582         KX_MACRO_addTypesToDict(d, KX_SCENE_SET_CAMERA, KX_SceneActuator::KX_SCENE_SET_CAMERA);
1583         KX_MACRO_addTypesToDict(d, KX_SCENE_ADD_FRONT_SCENE, KX_SceneActuator::KX_SCENE_ADD_FRONT_SCENE);
1584         KX_MACRO_addTypesToDict(d, KX_SCENE_ADD_BACK_SCENE, KX_SceneActuator::KX_SCENE_ADD_BACK_SCENE);
1585         KX_MACRO_addTypesToDict(d, KX_SCENE_REMOVE_SCENE, KX_SceneActuator::KX_SCENE_REMOVE_SCENE);
1586         KX_MACRO_addTypesToDict(d, KX_SCENE_SUSPEND, KX_SceneActuator::KX_SCENE_SUSPEND);
1587         KX_MACRO_addTypesToDict(d, KX_SCENE_RESUME, KX_SceneActuator::KX_SCENE_RESUME);
1588
1589         /* Parent Actuator Modes */
1590         KX_MACRO_addTypesToDict(d, KX_PARENT_SET, KX_ParentActuator::KX_PARENT_SET);
1591         KX_MACRO_addTypesToDict(d, KX_PARENT_REMOVE, KX_ParentActuator::KX_PARENT_REMOVE);
1592
1593         /* BL_ArmatureConstraint type */
1594         KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_TRACKTO, CONSTRAINT_TYPE_TRACKTO);
1595         KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_KINEMATIC);
1596         KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_ROTLIKE, CONSTRAINT_TYPE_ROTLIKE);
1597         KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_LOCLIKE, CONSTRAINT_TYPE_LOCLIKE);
1598         KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_MINMAX, CONSTRAINT_TYPE_MINMAX);
1599         KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_SIZELIKE, CONSTRAINT_TYPE_SIZELIKE);
1600         KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_LOCKTRACK, CONSTRAINT_TYPE_LOCKTRACK);
1601         KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_STRETCHTO, CONSTRAINT_TYPE_STRETCHTO);
1602         KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_CLAMPTO, CONSTRAINT_TYPE_CLAMPTO);
1603         KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_TRANSFORM, CONSTRAINT_TYPE_TRANSFORM);
1604         KX_MACRO_addTypesToDict(d, CONSTRAINT_TYPE_DISTLIMIT, CONSTRAINT_TYPE_DISTLIMIT);
1605         /* BL_ArmatureConstraint ik_type */
1606         KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_COPYPOSE, CONSTRAINT_IK_COPYPOSE);
1607         KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_DISTANCE, CONSTRAINT_IK_DISTANCE);
1608         /* BL_ArmatureConstraint ik_mode */
1609         KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_MODE_INSIDE, LIMITDIST_INSIDE);
1610         KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_MODE_OUTSIDE, LIMITDIST_OUTSIDE);
1611         KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_MODE_ONSURFACE, LIMITDIST_ONSURFACE);
1612         /* BL_ArmatureConstraint ik_flag */
1613         KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_FLAG_TIP, CONSTRAINT_IK_TIP);
1614         KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_FLAG_ROT, CONSTRAINT_IK_ROT);
1615         KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_FLAG_STRETCH, CONSTRAINT_IK_STRETCH);
1616         KX_MACRO_addTypesToDict(d, CONSTRAINT_IK_FLAG_POS, CONSTRAINT_IK_POS);
1617         /* KX_ArmatureSensor type */
1618         KX_MACRO_addTypesToDict(d, KX_ARMSENSOR_STATE_CHANGED, SENS_ARM_STATE_CHANGED);
1619         KX_MACRO_addTypesToDict(d, KX_ARMSENSOR_LIN_ERROR_BELOW, SENS_ARM_LIN_ERROR_BELOW);
1620         KX_MACRO_addTypesToDict(d, KX_ARMSENSOR_LIN_ERROR_ABOVE, SENS_ARM_LIN_ERROR_ABOVE);
1621         KX_MACRO_addTypesToDict(d, KX_ARMSENSOR_ROT_ERROR_BELOW, SENS_ARM_ROT_ERROR_BELOW);
1622         KX_MACRO_addTypesToDict(d, KX_ARMSENSOR_ROT_ERROR_ABOVE, SENS_ARM_ROT_ERROR_ABOVE);
1623
1624         /* BL_ArmatureActuator type */
1625         KX_MACRO_addTypesToDict(d, KX_ACT_ARMATURE_RUN, ACT_ARM_RUN);
1626         KX_MACRO_addTypesToDict(d, KX_ACT_ARMATURE_ENABLE, ACT_ARM_ENABLE);
1627         KX_MACRO_addTypesToDict(d, KX_ACT_ARMATURE_DISABLE, ACT_ARM_DISABLE);
1628         KX_MACRO_addTypesToDict(d, KX_ACT_ARMATURE_SETTARGET, ACT_ARM_SETTARGET);
1629         KX_MACRO_addTypesToDict(d, KX_ACT_ARMATURE_SETWEIGHT, ACT_ARM_SETWEIGHT);
1630
1631         /* BL_Armature Channel rotation_mode */
1632         KX_MACRO_addTypesToDict(d, ROT_MODE_QUAT, ROT_MODE_QUAT);
1633         KX_MACRO_addTypesToDict(d, ROT_MODE_XYZ, ROT_MODE_XYZ);
1634         KX_MACRO_addTypesToDict(d, ROT_MODE_XZY, ROT_MODE_XZY);
1635         KX_MACRO_addTypesToDict(d, ROT_MODE_YXZ, ROT_MODE_YXZ);
1636         KX_MACRO_addTypesToDict(d, ROT_MODE_YZX, ROT_MODE_YZX);
1637         KX_MACRO_addTypesToDict(d, ROT_MODE_ZXY, ROT_MODE_ZXY);
1638         KX_MACRO_addTypesToDict(d, ROT_MODE_ZYX, ROT_MODE_ZYX);
1639
1640         /* Steering actuator */
1641         KX_MACRO_addTypesToDict(d, KX_STEERING_SEEK, KX_SteeringActuator::KX_STEERING_SEEK);
1642         KX_MACRO_addTypesToDict(d, KX_STEERING_FLEE, KX_SteeringActuator::KX_STEERING_FLEE);
1643         KX_MACRO_addTypesToDict(d, KX_STEERING_PATHFOLLOWING, KX_SteeringActuator::KX_STEERING_PATHFOLLOWING);
1644
1645         /* KX_NavMeshObject render mode */
1646         KX_MACRO_addTypesToDict(d, RM_WALLS, KX_NavMeshObject::RM_WALLS);
1647         KX_MACRO_addTypesToDict(d, RM_POLYS, KX_NavMeshObject::RM_POLYS);
1648         KX_MACRO_addTypesToDict(d, RM_TRIS, KX_NavMeshObject::RM_TRIS);
1649
1650         // Check for errors
1651         if (PyErr_Occurred())
1652     {
1653                 Py_FatalError("can't initialize module bge.logic");
1654     }
1655
1656         return m;
1657 }
1658
1659 /* Explanation of 
1660  * 
1661  * - backupPySysObjects()               : stores sys.path in gp_OrigPythonSysPath
1662  * - initPySysObjects(main)     : initializes the blendfile and library paths
1663  * - restorePySysObjects()              : restores sys.path from gp_OrigPythonSysPath
1664  * 
1665  * These exist so the current blend dir "//" can always be used to import modules from.
1666  * the reason we need a few functions for this is that python is not only used by the game engine
1667  * so we cant just add to sys.path all the time, it would leave pythons state in a mess.
1668  * It would also be incorrect since loading blend files for new levels etc would alwasy add to sys.path
1669  * 
1670  * To play nice with blenders python, the sys.path is backed up and the current blendfile along
1671  * with all its lib paths are added to the sys path.
1672  * When loading a new blendfile, the original sys.path is restored and the new paths are added over the top.
1673  */
1674
1675 /**
1676  * So we can have external modules mixed with our blend files.
1677  */
1678 static void backupPySysObjects(void)
1679 {
1680         PyObject *sys_path= PySys_GetObject("path"); /* should never fail */
1681         PyObject *sys_mods= PySys_GetObject("modules"); /* should never fail */
1682         
1683         /* paths */
1684         Py_XDECREF(gp_OrigPythonSysPath); /* just incase its set */
1685         gp_OrigPythonSysPath = PyList_GetSlice(sys_path, 0, INT_MAX); /* copy the list */
1686         
1687         /* modules */
1688         Py_XDECREF(gp_OrigPythonSysModules); /* just incase its set */
1689         gp_OrigPythonSysModules = PyDict_Copy(sys_mods); /* copy the list */
1690         
1691 }
1692
1693 /* for initPySysObjects only,
1694  * takes a blend path and adds a scripts dir from it
1695  *
1696  * "/home/me/foo.blend" -> "/home/me/scripts"
1697  */
1698 static void initPySysObjects__append(PyObject *sys_path, char *filename)
1699 {
1700         PyObject *item;
1701         char expanded[FILE_MAXDIR + FILE_MAXFILE];
1702         
1703         BLI_split_dirfile(filename, expanded, NULL); /* get the dir part of filename only */
1704         BLI_path_abs(expanded, gp_GamePythonPath); /* filename from lib->filename is (always?) absolute, so this may not be needed but it wont hurt */
1705         BLI_cleanup_file(gp_GamePythonPath, expanded); /* Dont use BLI_cleanup_dir because it adds a slash - BREAKS WIN32 ONLY */
1706         item= PyUnicode_DecodeFSDefault(expanded);
1707         
1708 //      printf("SysPath - '%s', '%s', '%s'\n", expanded, filename, gp_GamePythonPath);
1709         
1710         if(PySequence_Index(sys_path, item) == -1) {
1711                 PyErr_Clear(); /* PySequence_Index sets a ValueError */
1712                 PyList_Insert(sys_path, 0, item);
1713         }
1714         
1715         Py_DECREF(item);
1716 }
1717 static void initPySysObjects(Main *maggie)
1718 {
1719         PyObject *sys_path= PySys_GetObject("path"); /* should never fail */
1720         
1721         if (gp_OrigPythonSysPath==NULL) {
1722                 /* backup */
1723                 backupPySysObjects();
1724         }
1725         else {
1726                 /* get the original sys path when the BGE started */
1727                 PyList_SetSlice(sys_path, 0, INT_MAX, gp_OrigPythonSysPath);
1728         }
1729         
1730         Library *lib= (Library *)maggie->library.first;
1731         
1732         while(lib) {
1733                 /* lib->name wont work in some cases (on win32),
1734                  * even when expanding with gp_GamePythonPath, using lib->filename is less trouble */
1735                 initPySysObjects__append(sys_path, lib->filepath);
1736                 lib= (Library *)lib->id.next;
1737         }
1738         
1739         initPySysObjects__append(sys_path, gp_GamePythonPath);
1740         
1741 //      fprintf(stderr, "\nNew Path: %d ", PyList_Size(sys_path));
1742 //      PyObject_Print(sys_path, stderr, 0);
1743 }
1744
1745 static void restorePySysObjects(void)
1746 {
1747         if (gp_OrigPythonSysPath==NULL)
1748                 return;
1749         
1750         PyObject *sys_path= PySys_GetObject("path"); /* should never fail */
1751         PyObject *sys_mods= PySys_GetObject("modules"); /* should never fail */
1752
1753         /* paths */
1754         PyList_SetSlice(sys_path, 0, INT_MAX, gp_OrigPythonSysPath);
1755         Py_DECREF(gp_OrigPythonSysPath);
1756         gp_OrigPythonSysPath= NULL;
1757         
1758         /* modules */
1759         PyDict_Clear(sys_mods);
1760         PyDict_Update(sys_mods, gp_OrigPythonSysModules);
1761         Py_DECREF(gp_OrigPythonSysModules);
1762         gp_OrigPythonSysModules= NULL;  
1763         
1764         
1765 //      fprintf(stderr, "\nRestore Path: %d ", PyList_Size(sys_path));
1766 //      PyObject_Print(sys_path, stderr, 0);
1767 }
1768
1769 // Copied from bpy_interface.c
1770 static struct _inittab bge_internal_modules[]= {
1771         {(char *)"mathutils", BPyInit_mathutils},
1772         {(char *)"bgl", BPyInit_bgl},
1773         {(char *)"blf", BPyInit_blf},
1774         {(char *)"aud", AUD_initPython},
1775         {NULL, NULL}
1776 };
1777
1778 /**
1779  * Python is not initialised.
1780  * see bpy_interface.c's BPY_python_start() which shares the same functionality in blender.
1781  */
1782 PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie, int argc, char** argv)
1783 {
1784         /* Yet another gotcha in the py api
1785          * Cant run PySys_SetArgv more then once because this adds the
1786          * binary dir to the sys.path each time.
1787          * Id have thaught python being totally restarted would make this ok but
1788          * somehow it remembers the sys.path - Campbell
1789          */
1790         static bool first_time = true;
1791         
1792 #if 0 // TODO - py3
1793         STR_String pname = progname;
1794         Py_SetProgramName(pname.Ptr());
1795 #endif
1796         Py_NoSiteFlag=1;
1797         Py_FrozenFlag=1;
1798
1799         /* must run before python initializes */
1800         PyImport_ExtendInittab(bge_internal_modules);
1801
1802         /* find local python installation */
1803         PyC_SetHomePath(BLI_get_folder(BLENDER_PYTHON, NULL));
1804
1805         Py_Initialize();
1806         
1807         if(argv && first_time) { /* browser plugins dont currently set this */
1808                 // Until python support ascii again, we use our own.
1809                 // PySys_SetArgv(argc, argv);
1810                 int i;
1811                 PyObject *py_argv= PyList_New(argc);
1812
1813                 for (i=0; i<argc; i++)
1814                         PyList_SET_ITEM(py_argv, i, PyC_UnicodeFromByte(argv[i]));
1815
1816                 PySys_SetObject("argv", py_argv);
1817                 Py_DECREF(py_argv);
1818         }
1819
1820         bpy_import_init(PyEval_GetBuiltins());
1821
1822         /* mathutils types are used by the BGE even if we dont import them */
1823         {
1824                 PyObject *mod= PyImport_ImportModuleLevel((char *)"mathutils", NULL, NULL, NULL, 0);
1825                 Py_DECREF(mod);
1826         }
1827
1828         initPyTypes();
1829         
1830         bpy_import_main_set(maggie);
1831         
1832         initPySysObjects(maggie);
1833         
1834         first_time = false;
1835         
1836         PyObjectPlus::ClearDeprecationWarning();
1837
1838         return PyC_DefaultNameSpace(NULL);
1839 }
1840
1841 void exitGamePlayerPythonScripting()
1842 {       
1843         /* Clean up the Python mouse and keyboard */
1844         delete gp_PythonKeyboard;
1845         gp_PythonKeyboard = NULL;
1846
1847         delete gp_PythonMouse;
1848         gp_PythonMouse = NULL;
1849
1850         /* since python restarts we cant let the python backup of the sys.path hang around in a global pointer */
1851         restorePySysObjects(); /* get back the original sys.path and clear the backup */
1852         
1853         Py_Finalize();
1854         bpy_import_main_set(NULL);
1855         PyObjectPlus::ClearDeprecationWarning();
1856 }
1857
1858
1859
1860 /**
1861  * Python is already initialized.
1862  */
1863 PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie)
1864 {
1865 #if 0 // XXX TODO Py3
1866         STR_String pname = progname;
1867         Py_SetProgramName(pname.Ptr());
1868 #endif
1869         Py_NoSiteFlag=1;
1870         Py_FrozenFlag=1;
1871
1872         initPyTypes();
1873         
1874         bpy_import_main_set(maggie);
1875         
1876         initPySysObjects(maggie);
1877
1878         PyObjectPlus::NullDeprecationWarning();
1879
1880         return PyC_DefaultNameSpace(NULL);
1881 }
1882
1883 void exitGamePythonScripting()
1884 {
1885         /* Clean up the Python mouse and keyboard */
1886         delete gp_PythonKeyboard;
1887         gp_PythonKeyboard = NULL;
1888
1889         delete gp_PythonMouse;
1890         gp_PythonMouse = NULL;
1891
1892         restorePySysObjects(); /* get back the original sys.path and clear the backup */
1893         bpy_import_main_set(NULL);
1894         PyObjectPlus::ClearDeprecationWarning();
1895 }
1896
1897 /* similar to the above functions except it sets up the namespace
1898  * and other more general things */
1899 void setupGamePython(KX_KetsjiEngine* ketsjiengine, KX_Scene* startscene, Main *blenderdata, PyObject * pyGlobalDict, PyObject **gameLogic, PyObject **gameLogic_keys, int argc, char** argv)
1900 {
1901         PyObject* dictionaryobject;
1902
1903         if(argv) /* player only */
1904                 dictionaryobject= initGamePlayerPythonScripting("Ketsji", psl_Lowest, blenderdata, argc, argv);
1905         else
1906                 dictionaryobject= initGamePythonScripting("Ketsji", psl_Lowest, blenderdata);
1907
1908         ketsjiengine->SetPyNamespace(dictionaryobject);
1909         initRasterizer(ketsjiengine->GetRasterizer(), ketsjiengine->GetCanvas());
1910         *gameLogic = initGameLogic(ketsjiengine, startscene);
1911
1912         /* is set in initGameLogic so only set here if we want it to persist between scenes */
1913         if(pyGlobalDict)
1914                 PyDict_SetItemString(PyModule_GetDict(*gameLogic), "globalDict", pyGlobalDict); // Same as importing the module.
1915
1916         *gameLogic_keys = PyDict_Keys(PyModule_GetDict(*gameLogic));
1917
1918         initGameKeys();
1919         initPythonConstraintBinding();
1920         initVideoTexture();
1921
1922         /* could be done a lot more nicely, but for now a quick way to get bge.* working */
1923         PyRun_SimpleString("sys = __import__('sys');mod = sys.modules['bge'] = type(sys)('bge');mod.__dict__.update({'logic':__import__('GameLogic'), 'render':__import__('Rasterizer'), 'events':__import__('GameKeys'), 'constraints':__import__('PhysicsConstraints'), 'types':__import__('GameTypes'), 'texture':__import__('VideoTexture')});");
1924 }
1925
1926 static struct PyModuleDef Rasterizer_module_def = {
1927         {}, /* m_base */
1928         "Rasterizer",  /* m_name */
1929         Rasterizer_module_documentation,  /* m_doc */
1930         0,  /* m_size */
1931         rasterizer_methods,  /* m_methods */
1932         0,  /* m_reload */
1933         0,  /* m_traverse */
1934         0,  /* m_clear */
1935         0,  /* m_free */
1936 };
1937
1938 PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas)
1939 {
1940         gp_Canvas = canvas;
1941         gp_Rasterizer = rasty;
1942
1943
1944   PyObject* m;
1945   PyObject* d;
1946   PyObject* item;
1947
1948         /* Use existing module where possible
1949          * be careful not to init any runtime vars after this */
1950         m = PyImport_ImportModule( "Rasterizer" );
1951         if(m) {
1952                 Py_DECREF(m);
1953                 return m;
1954         }
1955         else {
1956                 PyErr_Clear();
1957         
1958                 // Create the module and add the functions
1959                 m = PyModule_Create(&Rasterizer_module_def);
1960                 PyDict_SetItemString(PySys_GetObject("modules"), Rasterizer_module_def.m_name, m);
1961         }
1962
1963   // Add some symbolic constants to the module
1964   d = PyModule_GetDict(m);
1965   ErrorObject = PyUnicode_FromString("Rasterizer.error");
1966   PyDict_SetItemString(d, "error", ErrorObject);
1967   Py_DECREF(ErrorObject);
1968
1969   /* needed for get/setMaterialType */
1970   KX_MACRO_addTypesToDict(d, KX_TEXFACE_MATERIAL, KX_TEXFACE_MATERIAL);
1971   KX_MACRO_addTypesToDict(d, KX_BLENDER_MULTITEX_MATERIAL, KX_BLENDER_MULTITEX_MATERIAL);
1972   KX_MACRO_addTypesToDict(d, KX_BLENDER_GLSL_MATERIAL, KX_BLENDER_GLSL_MATERIAL);
1973
1974   // XXXX Add constants here
1975
1976   // Check for errors
1977   if (PyErr_Occurred())
1978     {
1979       Py_FatalError("can't initialize module Rasterizer");
1980     }
1981
1982   return d;
1983 }
1984
1985
1986
1987 /* ------------------------------------------------------------------------- */
1988 /* GameKeys: symbolic constants for key mapping                              */
1989 /* ------------------------------------------------------------------------- */
1990
1991 static char GameKeys_module_documentation[] =
1992 "This modules provides defines for key-codes"
1993 ;
1994
1995 static char gPyEventToString_doc[] =
1996 "EventToString(event) - Take a valid event from the GameKeys module or Keyboard Sensor and return a name"
1997 ;
1998
1999 static PyObject* gPyEventToString(PyObject*, PyObject* value)
2000 {
2001         PyObject* mod, *dict, *key, *val, *ret = NULL;
2002         Py_ssize_t pos = 0;
2003         
2004         mod = PyImport_ImportModule( "GameKeys" );
2005         if (!mod)
2006                 return NULL;
2007         
2008         dict = PyModule_GetDict(mod);
2009         
2010         while (PyDict_Next(dict, &pos, &key, &val)) {
2011                 if (PyObject_RichCompareBool(value, val, Py_EQ)) {
2012                         ret = key;
2013                         break;
2014                 }
2015         }
2016         
2017         PyErr_Clear(); // incase there was an error clearing
2018         Py_DECREF(mod);
2019         if (!ret)       PyErr_SetString(PyExc_ValueError, "GameKeys.EventToString(int): expected a valid int keyboard event");
2020         else            Py_INCREF(ret);
2021         
2022         return ret;
2023 }
2024
2025 static char gPyEventToCharacter_doc[] =
2026 "EventToCharacter(event, is_shift) - Take a valid event from the GameKeys module or Keyboard Sensor and return a character"
2027 ;
2028
2029 static PyObject* gPyEventToCharacter(PyObject*, PyObject* args)
2030 {
2031         int event, shift;
2032         if (!PyArg_ParseTuple(args,"ii:EventToCharacter", &event, &shift))
2033                 return NULL;
2034         
2035         if(IsPrintable(event)) {
2036                 char ch[2] = {'\0', '\0'};
2037                 ch[0] = ToCharacter(event, (bool)shift);
2038                 return PyUnicode_FromString(ch);
2039         }
2040         else {
2041                 return PyUnicode_FromString("");
2042         }
2043 }
2044
2045
2046 static struct PyMethodDef gamekeys_methods[] = {
2047         {"EventToCharacter", (PyCFunction)gPyEventToCharacter, METH_VARARGS, (const char *)gPyEventToCharacter_doc},
2048         {"EventToString", (PyCFunction)gPyEventToString, METH_O, (const char *)gPyEventToString_doc},
2049         { NULL, (PyCFunction) NULL, 0, NULL }
2050 };
2051
2052 static struct PyModuleDef GameKeys_module_def = {
2053         {}, /* m_base */
2054         "GameKeys",  /* m_name */
2055         GameKeys_module_documentation,  /* m_doc */
2056         0,  /* m_size */
2057         gamekeys_methods,  /* m_methods */
2058         0,  /* m_reload */
2059         0,  /* m_traverse */
2060         0,  /* m_clear */
2061         0,  /* m_free */
2062 };
2063
2064 PyObject* initGameKeys()
2065 {
2066         PyObject* m;
2067         PyObject* d;
2068         PyObject* item;
2069         
2070         /* Use existing module where possible */
2071         m = PyImport_ImportModule( "GameKeys" );
2072         if(m) {
2073                 Py_DECREF(m);
2074                 return m;
2075         }
2076         else {
2077                 PyErr_Clear();
2078         
2079                 // Create the module and add the functions
2080                 m = PyModule_Create(&GameKeys_module_def);
2081                 PyDict_SetItemString(PySys_GetObject("modules"), GameKeys_module_def.m_name, m);
2082         }
2083
2084         // Add some symbolic constants to the module
2085         d = PyModule_GetDict(m);
2086
2087         // XXXX Add constants here
2088
2089         KX_MACRO_addTypesToDict(d, AKEY, SCA_IInputDevice::KX_AKEY);
2090         KX_MACRO_addTypesToDict(d, BKEY, SCA_IInputDevice::KX_BKEY);
2091         KX_MACRO_addTypesToDict(d, CKEY, SCA_IInputDevice::KX_CKEY);
2092         KX_MACRO_addTypesToDict(d, DKEY, SCA_IInputDevice::KX_DKEY);
2093         KX_MACRO_addTypesToDict(d, EKEY, SCA_IInputDevice::KX_EKEY);
2094         KX_MACRO_addTypesToDict(d, FKEY, SCA_IInputDevice::KX_FKEY);
2095         KX_MACRO_addTypesToDict(d, GKEY, SCA_IInputDevice::KX_GKEY);
2096         KX_MACRO_addTypesToDict(d, HKEY, SCA_IInputDevice::KX_HKEY);
2097         KX_MACRO_addTypesToDict(d, IKEY, SCA_IInputDevice::KX_IKEY);
2098         KX_MACRO_addTypesToDict(d, JKEY, SCA_IInputDevice::KX_JKEY);
2099         KX_MACRO_addTypesToDict(d, KKEY, SCA_IInputDevice::KX_KKEY);
2100         KX_MACRO_addTypesToDict(d, LKEY, SCA_IInputDevice::KX_LKEY);
2101         KX_MACRO_addTypesToDict(d, MKEY, SCA_IInputDevice::KX_MKEY);
2102         KX_MACRO_addTypesToDict(d, NKEY, SCA_IInputDevice::KX_NKEY);
2103         KX_MACRO_addTypesToDict(d, OKEY, SCA_IInputDevice::KX_OKEY);
2104         KX_MACRO_addTypesToDict(d, PKEY, SCA_IInputDevice::KX_PKEY);
2105         KX_MACRO_addTypesToDict(d, QKEY, SCA_IInputDevice::KX_QKEY);
2106         KX_MACRO_addTypesToDict(d, RKEY, SCA_IInputDevice::KX_RKEY);
2107         KX_MACRO_addTypesToDict(d, SKEY, SCA_IInputDevice::KX_SKEY);
2108         KX_MACRO_addTypesToDict(d, TKEY, SCA_IInputDevice::KX_TKEY);
2109         KX_MACRO_addTypesToDict(d, UKEY, SCA_IInputDevice::KX_UKEY);
2110         KX_MACRO_addTypesToDict(d, VKEY, SCA_IInputDevice::KX_VKEY);
2111         KX_MACRO_addTypesToDict(d, WKEY, SCA_IInputDevice::KX_WKEY);
2112         KX_MACRO_addTypesToDict(d, XKEY, SCA_IInputDevice::KX_XKEY);
2113         KX_MACRO_addTypesToDict(d, YKEY, SCA_IInputDevice::KX_YKEY);
2114         KX_MACRO_addTypesToDict(d, ZKEY, SCA_IInputDevice::KX_ZKEY);
2115         
2116         KX_MACRO_addTypesToDict(d, ZEROKEY, SCA_IInputDevice::KX_ZEROKEY);              
2117         KX_MACRO_addTypesToDict(d, ONEKEY, SCA_IInputDevice::KX_ONEKEY);                
2118         KX_MACRO_addTypesToDict(d, TWOKEY, SCA_IInputDevice::KX_TWOKEY);                
2119         KX_MACRO_addTypesToDict(d, THREEKEY, SCA_IInputDevice::KX_THREEKEY);
2120         KX_MACRO_addTypesToDict(d, FOURKEY, SCA_IInputDevice::KX_FOURKEY);              
2121         KX_MACRO_addTypesToDict(d, FIVEKEY, SCA_IInputDevice::KX_FIVEKEY);              
2122         KX_MACRO_addTypesToDict(d, SIXKEY, SCA_IInputDevice::KX_SIXKEY);                
2123         KX_MACRO_addTypesToDict(d, SEVENKEY, SCA_IInputDevice::KX_SEVENKEY);
2124         KX_MACRO_addTypesToDict(d, EIGHTKEY, SCA_IInputDevice::KX_EIGHTKEY);
2125         KX_MACRO_addTypesToDict(d, NINEKEY, SCA_IInputDevice::KX_NINEKEY);              
2126                 
2127         KX_MACRO_addTypesToDict(d, CAPSLOCKKEY, SCA_IInputDevice::KX_CAPSLOCKKEY);
2128                 
2129         KX_MACRO_addTypesToDict(d, LEFTCTRLKEY, SCA_IInputDevice::KX_LEFTCTRLKEY);      
2130         KX_MACRO_addTypesToDict(d, LEFTALTKEY, SCA_IInputDevice::KX_LEFTALTKEY);                
2131         KX_MACRO_addTypesToDict(d, RIGHTALTKEY, SCA_IInputDevice::KX_RIGHTALTKEY);      
2132         KX_MACRO_addTypesToDict(d, RIGHTCTRLKEY, SCA_IInputDevice::KX_RIGHTCTRLKEY);    
2133         KX_MACRO_addTypesToDict(d, RIGHTSHIFTKEY, SCA_IInputDevice::KX_RIGHTSHIFTKEY);  
2134         KX_MACRO_addTypesToDict(d, LEFTSHIFTKEY, SCA_IInputDevice::KX_LEFTSHIFTKEY);
2135                 
2136         KX_MACRO_addTypesToDict(d, ESCKEY, SCA_IInputDevice::KX_ESCKEY);
2137         KX_MACRO_addTypesToDict(d, TABKEY, SCA_IInputDevice::KX_TABKEY);
2138         KX_MACRO_addTypesToDict(d, RETKEY, SCA_IInputDevice::KX_RETKEY);
2139         KX_MACRO_addTypesToDict(d, ENTERKEY, SCA_IInputDevice::KX_RETKEY);
2140         KX_MACRO_addTypesToDict(d, SPACEKEY, SCA_IInputDevice::KX_SPACEKEY);
2141         KX_MACRO_addTypesToDict(d, LINEFEEDKEY, SCA_IInputDevice::KX_LINEFEEDKEY);              
2142         KX_MACRO_addTypesToDict(d, BACKSPACEKEY, SCA_IInputDevice::KX_BACKSPACEKEY);
2143         KX_MACRO_addTypesToDict(d, DELKEY, SCA_IInputDevice::KX_DELKEY);
2144         KX_MACRO_addTypesToDict(d, SEMICOLONKEY, SCA_IInputDevice::KX_SEMICOLONKEY);
2145         KX_MACRO_addTypesToDict(d, PERIODKEY, SCA_IInputDevice::KX_PERIODKEY);          
2146         KX_MACRO_addTypesToDict(d, COMMAKEY, SCA_IInputDevice::KX_COMMAKEY);            
2147         KX_MACRO_addTypesToDict(d, QUOTEKEY, SCA_IInputDevice::KX_QUOTEKEY);            
2148         KX_MACRO_addTypesToDict(d, ACCENTGRAVEKEY, SCA_IInputDevice::KX_ACCENTGRAVEKEY);        
2149         KX_MACRO_addTypesToDict(d, MINUSKEY, SCA_IInputDevice::KX_MINUSKEY);            
2150         KX_MACRO_addTypesToDict(d, SLASHKEY, SCA_IInputDevice::KX_SLASHKEY);            
2151         KX_MACRO_addTypesToDict(d, BACKSLASHKEY, SCA_IInputDevice::KX_BACKSLASHKEY);
2152         KX_MACRO_addTypesToDict(d, EQUALKEY, SCA_IInputDevice::KX_EQUALKEY);            
2153         KX_MACRO_addTypesToDict(d, LEFTBRACKETKEY, SCA_IInputDevice::KX_LEFTBRACKETKEY);        
2154         KX_MACRO_addTypesToDict(d, RIGHTBRACKETKEY, SCA_IInputDevice::KX_RIGHTBRACKETKEY);      
2155                 
2156         KX_MACRO_addTypesToDict(d, LEFTARROWKEY, SCA_IInputDevice::KX_LEFTARROWKEY);
2157         KX_MACRO_addTypesToDict(d, DOWNARROWKEY, SCA_IInputDevice::KX_DOWNARROWKEY);
2158         KX_MACRO_addTypesToDict(d, RIGHTARROWKEY, SCA_IInputDevice::KX_RIGHTARROWKEY);  
2159         KX_MACRO_addTypesToDict(d, UPARROWKEY, SCA_IInputDevice::KX_UPARROWKEY);                
2160         
2161         KX_MACRO_addTypesToDict(d, PAD2 , SCA_IInputDevice::KX_PAD2);
2162         KX_MACRO_addTypesToDict(d, PAD4 , SCA_IInputDevice::KX_PAD4);
2163         KX_MACRO_addTypesToDict(d, PAD6 , SCA_IInputDevice::KX_PAD6);
2164         KX_MACRO_addTypesToDict(d, PAD8 , SCA_IInputDevice::KX_PAD8);
2165                 
2166         KX_MACRO_addTypesToDict(d, PAD1 , SCA_IInputDevice::KX_PAD1);
2167         KX_MACRO_addTypesToDict(d, PAD3 , SCA_IInputDevice::KX_PAD3);
2168         KX_MACRO_addTypesToDict(d, PAD5 , SCA_IInputDevice::KX_PAD5);
2169         KX_MACRO_addTypesToDict(d, PAD7 , SCA_IInputDevice::KX_PAD7);
2170         KX_MACRO_addTypesToDict(d, PAD9 , SCA_IInputDevice::KX_PAD9);
2171                 
2172         KX_MACRO_addTypesToDict(d, PADPERIOD, SCA_IInputDevice::KX_PADPERIOD);
2173         KX_MACRO_addTypesToDict(d, PADSLASHKEY, SCA_IInputDevice::KX_PADSLASHKEY);
2174         KX_MACRO_addTypesToDict(d, PADASTERKEY, SCA_IInputDevice::KX_PADASTERKEY);
2175                 
2176                 
2177         KX_MACRO_addTypesToDict(d, PAD0, SCA_IInputDevice::KX_PAD0);
2178         KX_MACRO_addTypesToDict(d, PADMINUS, SCA_IInputDevice::KX_PADMINUS);
2179         KX_MACRO_addTypesToDict(d, PADENTER, SCA_IInputDevice::KX_PADENTER);
2180         KX_MACRO_addTypesToDict(d, PADPLUSKEY, SCA_IInputDevice::KX_PADPLUSKEY);
2181                 
2182                 
2183         KX_MACRO_addTypesToDict(d, F1KEY , SCA_IInputDevice::KX_F1KEY);
2184         KX_MACRO_addTypesToDict(d, F2KEY , SCA_IInputDevice::KX_F2KEY);
2185         KX_MACRO_addTypesToDict(d, F3KEY , SCA_IInputDevice::KX_F3KEY);
2186         KX_MACRO_addTypesToDict(d, F4KEY , SCA_IInputDevice::KX_F4KEY);
2187         KX_MACRO_addTypesToDict(d, F5KEY , SCA_IInputDevice::KX_F5KEY);
2188         KX_MACRO_addTypesToDict(d, F6KEY , SCA_IInputDevice::KX_F6KEY);
2189         KX_MACRO_addTypesToDict(d, F7KEY , SCA_IInputDevice::KX_F7KEY);
2190         KX_MACRO_addTypesToDict(d, F8KEY , SCA_IInputDevice::KX_F8KEY);
2191         KX_MACRO_addTypesToDict(d, F9KEY , SCA_IInputDevice::KX_F9KEY);
2192         KX_MACRO_addTypesToDict(d, F10KEY, SCA_IInputDevice::KX_F10KEY);
2193         KX_MACRO_addTypesToDict(d, F11KEY, SCA_IInputDevice::KX_F11KEY);
2194         KX_MACRO_addTypesToDict(d, F12KEY, SCA_IInputDevice::KX_F12KEY);
2195         KX_MACRO_addTypesToDict(d, F13KEY, SCA_IInputDevice::KX_F13KEY);
2196         KX_MACRO_addTypesToDict(d, F14KEY, SCA_IInputDevice::KX_F14KEY);
2197         KX_MACRO_addTypesToDict(d, F15KEY, SCA_IInputDevice::KX_F15KEY);
2198         KX_MACRO_addTypesToDict(d, F16KEY, SCA_IInputDevice::KX_F16KEY);
2199         KX_MACRO_addTypesToDict(d, F17KEY, SCA_IInputDevice::KX_F17KEY);
2200         KX_MACRO_addTypesToDict(d, F18KEY, SCA_IInputDevice::KX_F18KEY);
2201         KX_MACRO_addTypesToDict(d, F19KEY, SCA_IInputDevice::KX_F19KEY);
2202                 
2203         KX_MACRO_addTypesToDict(d, PAUSEKEY, SCA_IInputDevice::KX_PAUSEKEY);
2204         KX_MACRO_addTypesToDict(d, INSERTKEY, SCA_IInputDevice::KX_INSERTKEY);
2205         KX_MACRO_addTypesToDict(d, HOMEKEY , SCA_IInputDevice::KX_HOMEKEY);
2206         KX_MACRO_addTypesToDict(d, PAGEUPKEY, SCA_IInputDevice::KX_PAGEUPKEY);
2207         KX_MACRO_addTypesToDict(d, PAGEDOWNKEY, SCA_IInputDevice::KX_PAGEDOWNKEY);
2208         KX_MACRO_addTypesToDict(d, ENDKEY, SCA_IInputDevice::KX_ENDKEY);
2209
2210         // MOUSE
2211         KX_MACRO_addTypesToDict(d, LEFTMOUSE, SCA_IInputDevice::KX_LEFTMOUSE);
2212         KX_MACRO_addTypesToDict(d, MIDDLEMOUSE, SCA_IInputDevice::KX_MIDDLEMOUSE);
2213         KX_MACRO_addTypesToDict(d, RIGHTMOUSE, SCA_IInputDevice::KX_RIGHTMOUSE);
2214         KX_MACRO_addTypesToDict(d, WHEELUPMOUSE, SCA_IInputDevice::KX_WHEELUPMOUSE);
2215         KX_MACRO_addTypesToDict(d, WHEELDOWNMOUSE, SCA_IInputDevice::KX_WHEELDOWNMOUSE);
2216         KX_MACRO_addTypesToDict(d, MOUSEX, SCA_IInputDevice::KX_MOUSEX);
2217         KX_MACRO_addTypesToDict(d, MOUSEY, SCA_IInputDevice::KX_MOUSEY);
2218
2219         // Check for errors
2220         if (PyErr_Occurred())
2221     {
2222                 Py_FatalError("can't initialize module GameKeys");
2223     }
2224
2225         return d;
2226 }
2227
2228 // utility function for loading and saving the globalDict
2229 int saveGamePythonConfig( char **marshal_buffer)
2230 {
2231         int marshal_length = 0;
2232         PyObject* gameLogic = PyImport_ImportModule("GameLogic");
2233         if (gameLogic) {
2234                 PyObject* pyGlobalDict = PyDict_GetItemString(PyModule_GetDict(gameLogic), "globalDict"); // Same as importing the module
2235                 if (pyGlobalDict) {
2236 #ifdef Py_MARSHAL_VERSION       
2237                         PyObject* pyGlobalDictMarshal = PyMarshal_WriteObjectToString(  pyGlobalDict, 2); // Py_MARSHAL_VERSION == 2 as of Py2.5
2238 #else
2239                         PyObject* pyGlobalDictMarshal = PyMarshal_WriteObjectToString(  pyGlobalDict ); 
2240 #endif
2241                         if (pyGlobalDictMarshal) {
2242                                 // for testing only
2243                                 // PyObject_Print(pyGlobalDictMarshal, stderr, 0);
2244                                 char *marshal_cstring;
2245                                 
2246                                 marshal_cstring = PyBytes_AsString(pyGlobalDictMarshal); // py3 uses byte arrays
2247                                 marshal_length= PyBytes_Size(pyGlobalDictMarshal);
2248                                 *marshal_buffer = new char[marshal_length + 1];
2249                                 memcpy(*marshal_buffer, marshal_cstring, marshal_length);
2250                                 Py_DECREF(pyGlobalDictMarshal);
2251                         } else {
2252                                 printf("Error, bge.logic.globalDict could not be marshal'd\n");
2253                         }
2254                 } else {
2255                         printf("Error, bge.logic.globalDict was removed\n");
2256                 }
2257                 Py_DECREF(gameLogic);
2258         } else {
2259                 PyErr_Clear();
2260                 printf("Error, bge.logic failed to import bge.logic.globalDict will be lost\n");
2261         }
2262         return marshal_length;
2263 }
2264
2265 int loadGamePythonConfig(char *marshal_buffer, int marshal_length)
2266 {
2267         /* Restore the dict */
2268         if (marshal_buffer) {
2269                 PyObject* gameLogic = PyImport_ImportModule("GameLogic");
2270
2271                 if (gameLogic) {
2272                         PyObject* pyGlobalDict = PyMarshal_ReadObjectFromString(marshal_buffer, marshal_length);
2273                         if (pyGlobalDict) {
2274                                 PyObject* pyGlobalDict_orig = PyDict_GetItemString(PyModule_GetDict(gameLogic), "globalDict"); // Same as importing the module.
2275                                 if (pyGlobalDict_orig) {
2276                                         PyDict_Clear(pyGlobalDict_orig);
2277                                         PyDict_Update(pyGlobalDict_orig, pyGlobalDict);
2278                                 } else {
2279                                         /* this should not happen, but cant find the original globalDict, just assign it then */
2280                                         PyDict_SetItemString(PyModule_GetDict(gameLogic), "globalDict", pyGlobalDict); // Same as importing the module.
2281                                 }
2282                                 Py_DECREF(gameLogic);
2283                                 Py_DECREF(pyGlobalDict);
2284                                 return 1;
2285                         } else {
2286                                 Py_DECREF(gameLogic);
2287                                 PyErr_Clear();
2288                                 printf("Error could not marshall string\n");
2289                         }
2290                 } else {
2291                         PyErr_Clear();
2292                         printf("Error, bge.logic failed to import bge.logic.globalDict will be lost\n");
2293                 }       
2294         }
2295         return 0;
2296 }
2297
2298 void pathGamePythonConfig( char *path )
2299 {
2300         int len = strlen(gp_GamePythonPathOrig); // Always use the first loaded blend filename
2301         
2302         BLI_strncpy(path, gp_GamePythonPathOrig, sizeof(gp_GamePythonPathOrig));
2303
2304         /* replace extension */
2305         if (BLI_testextensie(path, ".blend")) {
2306                 strcpy(path+(len-6), ".bgeconf");
2307         } else {
2308                 strcpy(path+len, ".bgeconf");
2309         }
2310 }
2311
2312 void setGamePythonPath(char *path)
2313 {
2314         BLI_strncpy(gp_GamePythonPath, path, sizeof(gp_GamePythonPath));
2315         BLI_cleanup_file(NULL, gp_GamePythonPath); /* not absolutely needed but makes resolving path problems less confusing later */
2316         
2317         if (gp_GamePythonPathOrig[0] == '\0')
2318                 BLI_strncpy(gp_GamePythonPathOrig, path, sizeof(gp_GamePythonPathOrig));
2319 }
2320
2321 // we need this so while blender is open (not blenderplayer)
2322 // loading new blendfiles will reset this on starting the
2323 // engine but loading blend files within the BGE wont overwrite gp_GamePythonPathOrig
2324 void resetGamePythonPath()
2325 {
2326         gp_GamePythonPathOrig[0] = '\0';
2327 }
2328
2329 #endif // WITH_PYTHON