Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 * Blender's Ketsji startpoint 00027 */ 00028 00034 #include <signal.h> 00035 #include <stdlib.h> 00036 #include <stdio.h> 00037 00038 #if defined(WIN32) && !defined(FREE_WINDOWS) 00039 // don't show stl-warnings 00040 #pragma warning (disable:4786) 00041 #endif 00042 00043 #include "GL/glew.h" 00044 00045 #include "KX_BlenderGL.h" 00046 #include "KX_BlenderCanvas.h" 00047 #include "KX_BlenderKeyboardDevice.h" 00048 #include "KX_BlenderMouseDevice.h" 00049 #include "KX_BlenderRenderTools.h" 00050 #include "KX_BlenderSystem.h" 00051 #include "BL_Material.h" 00052 00053 #include "KX_KetsjiEngine.h" 00054 #include "KX_BlenderSceneConverter.h" 00055 #include "KX_PythonInit.h" 00056 #include "KX_PyConstraintBinding.h" 00057 00058 #include "RAS_GLExtensionManager.h" 00059 #include "RAS_OpenGLRasterizer.h" 00060 #include "RAS_VAOpenGLRasterizer.h" 00061 #include "RAS_ListRasterizer.h" 00062 00063 #include "NG_LoopBackNetworkDeviceInterface.h" 00064 00065 #include "BL_System.h" 00066 00067 #include "GPU_extensions.h" 00068 #include "Value.h" 00069 00070 00071 00072 #ifdef __cplusplus 00073 extern "C" { 00074 #endif 00075 /***/ 00076 #include "DNA_view3d_types.h" 00077 #include "DNA_screen_types.h" 00078 #include "DNA_userdef_types.h" 00079 #include "DNA_windowmanager_types.h" 00080 #include "BKE_global.h" 00081 #include "BKE_report.h" 00082 /* #include "BKE_screen.h" */ /* cant include this because of 'new' function name */ 00083 extern float BKE_screen_view3d_zoom_to_fac(float camzoom); 00084 00085 00086 //XXX #include "BIF_screen.h" 00087 //XXX #include "BIF_scrarea.h" 00088 00089 #include "BKE_main.h" 00090 #include "BLI_blenlib.h" 00091 #include "BLO_readfile.h" 00092 #include "DNA_scene_types.h" 00093 #include "BKE_ipo.h" 00094 /***/ 00095 00096 //XXX #include "BSE_headerbuttons.h" 00097 #include "BKE_context.h" 00098 #include "../../blender/windowmanager/WM_types.h" 00099 #include "../../blender/windowmanager/wm_window.h" 00100 #include "../../blender/windowmanager/wm_event_system.h" 00101 #ifdef __cplusplus 00102 } 00103 #endif 00104 00105 #ifdef WITH_AUDASPACE 00106 # include "AUD_C-API.h" 00107 # include "AUD_I3DDevice.h" 00108 # include "AUD_IDevice.h" 00109 #endif 00110 00111 static BlendFileData *load_game_data(char *filename) 00112 { 00113 ReportList reports; 00114 BlendFileData *bfd; 00115 00116 BKE_reports_init(&reports, RPT_STORE); 00117 bfd= BLO_read_from_file(filename, &reports); 00118 00119 if (!bfd) { 00120 printf("Loading %s failed: ", filename); 00121 BKE_reports_print(&reports, RPT_ERROR); 00122 } 00123 00124 BKE_reports_clear(&reports); 00125 00126 return bfd; 00127 } 00128 00129 extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing) 00130 { 00131 /* context values */ 00132 struct wmWindow *win= CTX_wm_window(C); 00133 struct Scene *startscene= CTX_data_scene(C); 00134 struct Main* maggie1= CTX_data_main(C); 00135 00136 00137 RAS_Rect area_rect; 00138 area_rect.SetLeft(cam_frame->xmin); 00139 area_rect.SetBottom(cam_frame->ymin); 00140 area_rect.SetRight(cam_frame->xmax); 00141 area_rect.SetTop(cam_frame->ymax); 00142 00143 int exitrequested = KX_EXIT_REQUEST_NO_REQUEST; 00144 Main* blenderdata = maggie1; 00145 00146 char* startscenename = startscene->id.name+2; 00147 char pathname[FILE_MAXDIR+FILE_MAXFILE], oldsce[FILE_MAXDIR+FILE_MAXFILE]; 00148 STR_String exitstring = ""; 00149 BlendFileData *bfd= NULL; 00150 00151 BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); 00152 BLI_strncpy(oldsce, G.main->name, sizeof(oldsce)); 00153 #ifdef WITH_PYTHON 00154 resetGamePythonPath(); // need this so running a second time wont use an old blendfiles path 00155 setGamePythonPath(G.main->name); 00156 00157 // Acquire Python's GIL (global interpreter lock) 00158 // so we can safely run Python code and API calls 00159 PyGILState_STATE gilstate = PyGILState_Ensure(); 00160 00161 PyObject *pyGlobalDict = PyDict_New(); /* python utility storage, spans blend file loading */ 00162 #endif 00163 00164 bgl::InitExtensions(true); 00165 00166 // VBO code for derived mesh is not compatible with BGE (couldn't find why), so disable 00167 int disableVBO = (U.gameflags & USER_DISABLE_VBO); 00168 U.gameflags |= USER_DISABLE_VBO; 00169 00170 // Globals to be carried on over blender files 00171 GlobalSettings gs; 00172 gs.matmode= startscene->gm.matmode; 00173 gs.glslflag= startscene->gm.flag; 00174 00175 do 00176 { 00177 View3D *v3d= CTX_wm_view3d(C); 00178 RegionView3D *rv3d= CTX_wm_region_view3d(C); 00179 00180 // get some preferences 00181 SYS_SystemHandle syshandle = SYS_GetSystem(); 00182 bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0); 00183 bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0); 00184 bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0); 00185 bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0); 00186 bool animation_record = (SYS_GetCommandLineInt(syshandle, "animation_record", 0) != 0); 00187 bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0); 00188 #ifdef WITH_PYTHON 00189 bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0); 00190 #endif 00191 bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0); 00192 bool mouse_state = startscene->gm.flag & GAME_SHOW_MOUSE; 00193 bool restrictAnimFPS = startscene->gm.flag & GAME_RESTRICT_ANIM_UPDATES; 00194 00195 if(animation_record) usefixed= true; /* override since you's always want fixed time for sim recording */ 00196 00197 // create the canvas, rasterizer and rendertools 00198 RAS_ICanvas* canvas = new KX_BlenderCanvas(win, area_rect, ar); 00199 00200 // default mouse state set on render panel 00201 if (mouse_state) 00202 canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); 00203 else 00204 canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); 00205 RAS_IRenderTools* rendertools = new KX_BlenderRenderTools(); 00206 RAS_IRasterizer* rasterizer = NULL; 00207 00208 if(displaylists) { 00209 if (GLEW_VERSION_1_1 && !novertexarrays) 00210 rasterizer = new RAS_ListRasterizer(canvas, true, true); 00211 else 00212 rasterizer = new RAS_ListRasterizer(canvas); 00213 } 00214 else if (GLEW_VERSION_1_1 && !novertexarrays) 00215 rasterizer = new RAS_VAOpenGLRasterizer(canvas, false); 00216 else 00217 rasterizer = new RAS_OpenGLRasterizer(canvas); 00218 00219 // create the inputdevices 00220 KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice(); 00221 KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice(); 00222 00223 // create a networkdevice 00224 NG_NetworkDeviceInterface* networkdevice = new 00225 NG_LoopBackNetworkDeviceInterface(); 00226 00227 // 00228 // create a ketsji/blendersystem (only needed for timing and stuff) 00229 KX_BlenderSystem* kxsystem = new KX_BlenderSystem(); 00230 00231 // create the ketsjiengine 00232 KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem); 00233 00234 // set the devices 00235 ketsjiengine->SetKeyboardDevice(keyboarddevice); 00236 ketsjiengine->SetMouseDevice(mousedevice); 00237 ketsjiengine->SetNetworkDevice(networkdevice); 00238 ketsjiengine->SetCanvas(canvas); 00239 ketsjiengine->SetRenderTools(rendertools); 00240 ketsjiengine->SetRasterizer(rasterizer); 00241 ketsjiengine->SetUseFixedTime(usefixed); 00242 ketsjiengine->SetTimingDisplay(frameRate, profile, properties); 00243 ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS); 00244 KX_KetsjiEngine::SetExitKey(ConvertKeyCode(startscene->gm.exitkey)); 00245 00246 //set the global settings (carried over if restart/load new files) 00247 ketsjiengine->SetGlobalSettings(&gs); 00248 00249 #ifdef WITH_PYTHON 00250 CValue::SetDeprecationWarnings(nodepwarnings); 00251 #endif 00252 00253 //lock frame and camera enabled - storing global values 00254 int tmp_lay= startscene->lay; 00255 Object *tmp_camera = startscene->camera; 00256 00257 if (v3d->scenelock==0){ 00258 startscene->lay= v3d->lay; 00259 startscene->camera= v3d->camera; 00260 } 00261 00262 // some blender stuff 00263 float camzoom; 00264 int draw_letterbox = 0; 00265 00266 if(rv3d->persp==RV3D_CAMOB) { 00267 if(startscene->gm.framing.type == SCE_GAMEFRAMING_BARS) { /* Letterbox */ 00268 camzoom = 1.0f; 00269 draw_letterbox = 1; 00270 } 00271 else { 00272 camzoom = 1.0 / BKE_screen_view3d_zoom_to_fac(rv3d->camzoom); 00273 } 00274 } 00275 else { 00276 camzoom = 2.0; 00277 } 00278 00279 00280 ketsjiengine->SetDrawType(v3d->drawtype); 00281 ketsjiengine->SetCameraZoom(camzoom); 00282 00283 // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file 00284 if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME) 00285 { 00286 exitrequested = KX_EXIT_REQUEST_NO_REQUEST; 00287 if (bfd) BLO_blendfiledata_free(bfd); 00288 00289 char basedpath[FILE_MAX]; 00290 // base the actuator filename with respect 00291 // to the original file working directory 00292 00293 if (exitstring != "") 00294 strcpy(basedpath, exitstring.Ptr()); 00295 00296 // load relative to the last loaded file, this used to be relative 00297 // to the first file but that makes no sense, relative paths in 00298 // blend files should be relative to that file, not some other file 00299 // that happened to be loaded first 00300 BLI_path_abs(basedpath, pathname); 00301 bfd = load_game_data(basedpath); 00302 00303 // if it wasn't loaded, try it forced relative 00304 if (!bfd) 00305 { 00306 // just add "//" in front of it 00307 char temppath[242]; 00308 strcpy(temppath, "//"); 00309 strcat(temppath, basedpath); 00310 00311 BLI_path_abs(temppath, pathname); 00312 bfd = load_game_data(temppath); 00313 } 00314 00315 // if we got a loaded blendfile, proceed 00316 if (bfd) 00317 { 00318 blenderdata = bfd->main; 00319 startscenename = bfd->curscene->id.name + 2; 00320 00321 if(blenderdata) { 00322 BLI_strncpy(G.main->name, blenderdata->name, sizeof(G.main->name)); 00323 BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); 00324 #ifdef WITH_PYTHON 00325 setGamePythonPath(G.main->name); 00326 #endif 00327 } 00328 } 00329 // else forget it, we can't find it 00330 else 00331 { 00332 exitrequested = KX_EXIT_REQUEST_QUIT_GAME; 00333 } 00334 } 00335 00336 Scene *scene= bfd ? bfd->curscene : (Scene *)BLI_findstring(&blenderdata->scene, startscenename, offsetof(ID, name) + 2); 00337 00338 if (scene) 00339 { 00340 int startFrame = scene->r.cfra; 00341 ketsjiengine->SetAnimRecordMode(animation_record, startFrame); 00342 00343 // Quad buffered needs a special window. 00344 if(scene->gm.stereoflag == STEREO_ENABLED){ 00345 if (scene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) 00346 rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) scene->gm.stereomode); 00347 00348 rasterizer->SetEyeSeparation(scene->gm.eyeseparation); 00349 } 00350 00351 rasterizer->SetBackColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 0.0f); 00352 } 00353 00354 if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME) 00355 { 00356 if (rv3d->persp != RV3D_CAMOB) 00357 { 00358 ketsjiengine->EnableCameraOverride(startscenename); 00359 ketsjiengine->SetCameraOverrideUseOrtho((rv3d->persp == RV3D_ORTHO)); 00360 ketsjiengine->SetCameraOverrideProjectionMatrix(MT_CmMatrix4x4(rv3d->winmat)); 00361 ketsjiengine->SetCameraOverrideViewMatrix(MT_CmMatrix4x4(rv3d->viewmat)); 00362 if(rv3d->persp == RV3D_ORTHO) 00363 { 00364 ketsjiengine->SetCameraOverrideClipping(-v3d->far, v3d->far); 00365 } 00366 else 00367 { 00368 ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far); 00369 } 00370 ketsjiengine->SetCameraOverrideLens(v3d->lens); 00371 } 00372 00373 // create a scene converter, create and convert the startingscene 00374 KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine); 00375 ketsjiengine->SetSceneConverter(sceneconverter); 00376 sceneconverter->addInitFromFrame=false; 00377 if (always_use_expand_framing) 00378 sceneconverter->SetAlwaysUseExpandFraming(true); 00379 00380 bool usemat = false, useglslmat = false; 00381 00382 if(GLEW_ARB_multitexture && GLEW_VERSION_1_1) 00383 usemat = true; 00384 00385 if(GPU_glsl_support()) 00386 useglslmat = true; 00387 else if(gs.matmode == GAME_MAT_GLSL) 00388 usemat = false; 00389 00390 if(usemat && (gs.matmode != GAME_MAT_TEXFACE)) 00391 sceneconverter->SetMaterials(true); 00392 if(useglslmat && (gs.matmode == GAME_MAT_GLSL)) 00393 sceneconverter->SetGLSLMaterials(true); 00394 00395 KX_Scene* startscene = new KX_Scene(keyboarddevice, 00396 mousedevice, 00397 networkdevice, 00398 startscenename, 00399 scene, 00400 canvas); 00401 00402 #ifdef WITH_PYTHON 00403 // some python things 00404 PyObject *gameLogic, *gameLogic_keys; 00405 setupGamePython(ketsjiengine, startscene, blenderdata, pyGlobalDict, &gameLogic, &gameLogic_keys, 0, NULL); 00406 #endif // WITH_PYTHON 00407 00408 //initialize Dome Settings 00409 if(scene->gm.stereoflag == STEREO_DOME) 00410 ketsjiengine->InitDome(scene->gm.dome.res, scene->gm.dome.mode, scene->gm.dome.angle, scene->gm.dome.resbuf, scene->gm.dome.tilt, scene->gm.dome.warptext); 00411 00412 // initialize 3D Audio Settings 00413 AUD_I3DDevice* dev = AUD_get3DDevice(); 00414 if(dev) 00415 { 00416 dev->setSpeedOfSound(scene->audio.speed_of_sound); 00417 dev->setDopplerFactor(scene->audio.doppler_factor); 00418 dev->setDistanceModel(AUD_DistanceModel(scene->audio.distance_model)); 00419 } 00420 00421 // from see blender.c: 00422 // FIXME: this version patching should really be part of the file-reading code, 00423 // but we still get too many unrelated data-corruption crashes otherwise... 00424 if (blenderdata->versionfile < 250) 00425 do_versions_ipos_to_animato(blenderdata); 00426 00427 if (sceneconverter) 00428 { 00429 // convert and add scene 00430 sceneconverter->ConvertScene( 00431 startscene, 00432 rendertools, 00433 canvas); 00434 ketsjiengine->AddScene(startscene); 00435 00436 // init the rasterizer 00437 rasterizer->Init(); 00438 00439 // start the engine 00440 ketsjiengine->StartEngine(true); 00441 00442 00443 // Set the animation playback rate for ipo's and actions 00444 // the framerate below should patch with FPS macro defined in blendef.h 00445 // Could be in StartEngine set the framerate, we need the scene to do this 00446 ketsjiengine->SetAnimFrameRate(FPS); 00447 00448 // the mainloop 00449 printf("\nBlender Game Engine Started\n"); 00450 while (!exitrequested) 00451 { 00452 // first check if we want to exit 00453 exitrequested = ketsjiengine->GetExitCode(); 00454 00455 // kick the engine 00456 bool render = ketsjiengine->NextFrame(); 00457 00458 if (render) 00459 { 00460 if(draw_letterbox) { 00461 // Clear screen to border color 00462 // We do this here since we set the canvas to be within the frames. This means the engine 00463 // itself is unaware of the extra space, so we clear the whole region for it. 00464 glClearColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 1.0f); 00465 glViewport(ar->winrct.xmin, ar->winrct.ymin, 00466 ar->winrct.xmax - ar->winrct.xmin, ar->winrct.ymax - ar->winrct.ymin); 00467 glClear(GL_COLOR_BUFFER_BIT); 00468 } 00469 00470 // render the frame 00471 ketsjiengine->Render(); 00472 } 00473 00474 wm_window_process_events_nosleep(); 00475 00476 // test for the ESC key 00477 //XXX while (qtest()) 00478 while(wmEvent *event= (wmEvent *)win->queue.first) 00479 { 00480 short val = 0; 00481 //unsigned short event = 0; //XXX extern_qread(&val); 00482 00483 if (keyboarddevice->ConvertBlenderEvent(event->type,event->val)) 00484 exitrequested = KX_EXIT_REQUEST_BLENDER_ESC; 00485 00486 /* Coordinate conversion... where 00487 * should this really be? 00488 */ 00489 if (event->type==MOUSEMOVE) { 00490 /* Note, not nice! XXX 2.5 event hack */ 00491 val = event->x - ar->winrct.xmin; 00492 mousedevice->ConvertBlenderEvent(MOUSEX, val); 00493 00494 val = ar->winy - (event->y - ar->winrct.ymin) - 1; 00495 mousedevice->ConvertBlenderEvent(MOUSEY, val); 00496 } 00497 else { 00498 mousedevice->ConvertBlenderEvent(event->type,event->val); 00499 } 00500 00501 BLI_remlink(&win->queue, event); 00502 wm_event_free(event); 00503 } 00504 00505 if(win != CTX_wm_window(C)) { 00506 exitrequested= KX_EXIT_REQUEST_OUTSIDE; /* window closed while bge runs */ 00507 } 00508 } 00509 printf("Blender Game Engine Finished\n"); 00510 exitstring = ketsjiengine->GetExitString(); 00511 gs = *(ketsjiengine->GetGlobalSettings()); 00512 00513 00514 // when exiting the mainloop 00515 #ifdef WITH_PYTHON 00516 // Clears the dictionary by hand: 00517 // This prevents, extra references to global variables 00518 // inside the GameLogic dictionary when the python interpreter is finalized. 00519 // which allows the scene to safely delete them :) 00520 // see: (space.c)->start_game 00521 00522 //PyDict_Clear(PyModule_GetDict(gameLogic)); 00523 00524 // Keep original items, means python plugins will autocomplete members 00525 PyObject *gameLogic_keys_new = PyDict_Keys(PyModule_GetDict(gameLogic)); 00526 const Py_ssize_t numitems= PyList_GET_SIZE(gameLogic_keys_new); 00527 Py_ssize_t listIndex; 00528 for (listIndex=0; listIndex < numitems; listIndex++) { 00529 PyObject* item = PyList_GET_ITEM(gameLogic_keys_new, listIndex); 00530 if (!PySequence_Contains(gameLogic_keys, item)) { 00531 PyDict_DelItem( PyModule_GetDict(gameLogic), item); 00532 } 00533 } 00534 Py_DECREF(gameLogic_keys_new); 00535 gameLogic_keys_new = NULL; 00536 #endif 00537 ketsjiengine->StopEngine(); 00538 #ifdef WITH_PYTHON 00539 exitGamePythonScripting(); 00540 #endif 00541 networkdevice->Disconnect(); 00542 } 00543 if (sceneconverter) 00544 { 00545 delete sceneconverter; 00546 sceneconverter = NULL; 00547 } 00548 00549 #ifdef WITH_PYTHON 00550 Py_DECREF(gameLogic_keys); 00551 gameLogic_keys = NULL; 00552 #endif 00553 } 00554 //lock frame and camera enabled - restoring global values 00555 if (v3d->scenelock==0){ 00556 startscene->lay= tmp_lay; 00557 startscene->camera= tmp_camera; 00558 } 00559 00560 if(exitrequested != KX_EXIT_REQUEST_OUTSIDE) 00561 { 00562 // set the cursor back to normal 00563 canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); 00564 } 00565 00566 // clean up some stuff 00567 if (ketsjiengine) 00568 { 00569 delete ketsjiengine; 00570 ketsjiengine = NULL; 00571 } 00572 if (kxsystem) 00573 { 00574 delete kxsystem; 00575 kxsystem = NULL; 00576 } 00577 if (networkdevice) 00578 { 00579 delete networkdevice; 00580 networkdevice = NULL; 00581 } 00582 if (keyboarddevice) 00583 { 00584 delete keyboarddevice; 00585 keyboarddevice = NULL; 00586 } 00587 if (mousedevice) 00588 { 00589 delete mousedevice; 00590 mousedevice = NULL; 00591 } 00592 if (rasterizer) 00593 { 00594 delete rasterizer; 00595 rasterizer = NULL; 00596 } 00597 if (rendertools) 00598 { 00599 delete rendertools; 00600 rendertools = NULL; 00601 } 00602 if (canvas) 00603 { 00604 delete canvas; 00605 canvas = NULL; 00606 } 00607 00608 // stop all remaining playing sounds 00609 AUD_getDevice()->stopAll(); 00610 00611 } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME); 00612 00613 if (!disableVBO) 00614 U.gameflags &= ~USER_DISABLE_VBO; 00615 00616 if (bfd) BLO_blendfiledata_free(bfd); 00617 00618 BLI_strncpy(G.main->name, oldsce, sizeof(G.main->name)); 00619 00620 #ifdef WITH_PYTHON 00621 Py_DECREF(pyGlobalDict); 00622 00623 // Release Python's GIL 00624 PyGILState_Release(gilstate); 00625 #endif 00626 00627 }