void GPG_Application::exitEngine() { // We only want to kill the engine if it has been initialized if (!m_engineInitialized) return; BKE_sound_exit(); if (m_ketsjiengine) { stopEngine(); delete m_ketsjiengine; m_ketsjiengine = 0; } if (m_kxsystem) { delete m_kxsystem; m_kxsystem = 0; } if (m_networkdevice) { delete m_networkdevice; m_networkdevice = 0; } if (m_mouse) { delete m_mouse; m_mouse = 0; } if (m_keyboard) { delete m_keyboard; m_keyboard = 0; } if (m_rasterizer) { delete m_rasterizer; m_rasterizer = 0; } if (m_canvas) { delete m_canvas; m_canvas = 0; } GPU_exit(); #ifdef WITH_PYTHON // Call this after we're sure nothing needs Python anymore (e.g., destructors) exitGamePlayerPythonScripting(); #endif m_exitRequested = 0; m_engineInitialized = false; }
void BKE_sound_init(Main *bmain) { /* Make sure no instance of the sound system is running, otherwise we get leaks. */ BKE_sound_exit(); AUD_DeviceSpecs specs; int device, buffersize; const char *device_name; device = U.audiodevice; buffersize = U.mixbufsize; specs.channels = U.audiochannels; specs.format = U.audioformat; specs.rate = U.audiorate; if (force_device == NULL) { int i; char **names = BKE_sound_get_device_names(); device_name = names[0]; /* make sure device is within the bounds of the array */ for (i = 0; names[i]; i++) { if (i == device) { device_name = names[i]; } } } else { device_name = force_device; } if (buffersize < 128) { buffersize = 1024; } if (specs.rate < AUD_RATE_8000) { specs.rate = AUD_RATE_48000; } if (specs.format <= AUD_FORMAT_INVALID) { specs.format = AUD_FORMAT_S16; } if (specs.channels <= AUD_CHANNELS_INVALID) { specs.channels = AUD_CHANNELS_STEREO; } if (!(sound_device = AUD_init(device_name, specs, buffersize, "Blender"))) { sound_device = AUD_init("Null", specs, buffersize, "Blender"); } BKE_sound_init_main(bmain); }
/** * \note doesn't run exit() call #WM_exit() for that. */ void WM_exit_ext(bContext *C, const bool do_python) { wmWindowManager *wm = C ? CTX_wm_manager(C) : NULL; /* first wrap up running stuff, we assume only the active WM is running */ /* modal handlers are on window level freed, others too? */ /* note; same code copied in wm_files.c */ if (C && wm) { wmWindow *win; if (!G.background) { struct MemFile *undo_memfile = wm->undo_stack ? ED_undosys_stack_memfile_get_active(wm->undo_stack) : NULL; if ((U.uiflag2 & USER_KEEP_SESSION) || (undo_memfile != NULL)) { /* save the undo state as quit.blend */ char filename[FILE_MAX]; bool has_edited; int fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_HISTORY); BLI_make_file_string("/", filename, BKE_tempdir_base(), BLENDER_QUIT_FILE); has_edited = ED_editors_flush_edits(C, false); if ((has_edited && BLO_write_file(CTX_data_main(C), filename, fileflags, NULL, NULL)) || (undo_memfile && BLO_memfile_write_file(undo_memfile, filename))) { printf("Saved session recovery to '%s'\n", filename); } } } WM_jobs_kill_all(wm); for (win = wm->windows.first; win; win = win->next) { CTX_wm_window_set(C, win); /* needed by operator close callbacks */ WM_event_remove_handlers(C, &win->handlers); WM_event_remove_handlers(C, &win->modalhandlers); ED_screen_exit(C, win, win->screen); } } BKE_addon_pref_type_free(); wm_operatortype_free(); wm_dropbox_free(); WM_menutype_free(); WM_uilisttype_free(); /* all non-screen and non-space stuff editors did, like editmode */ if (C) ED_editors_exit(C); ED_undosys_type_free(); // XXX // BIF_GlobalReebFree(); // BIF_freeRetarget(); BIF_freeTemplates(C); free_openrecent(); BKE_mball_cubeTable_free(); /* render code might still access databases */ RE_FreeAllRender(); RE_engines_exit(); ED_preview_free_dbase(); /* frees a Main dbase, before BKE_blender_free! */ if (C && wm) wm_free_reports(C); /* before BKE_blender_free! - since the ListBases get freed there */ BKE_sequencer_free_clipboard(); /* sequencer.c */ BKE_tracking_clipboard_free(); BKE_mask_clipboard_free(); BKE_vfont_clipboard_free(); #ifdef WITH_COMPOSITOR COM_deinitialize(); #endif BKE_blender_free(); /* blender.c, does entire library and spacetypes */ // free_matcopybuf(); ANIM_fcurves_copybuf_free(); ANIM_drivers_copybuf_free(); ANIM_driver_vars_copybuf_free(); ANIM_fmodifiers_copybuf_free(); ED_gpencil_anim_copybuf_free(); ED_gpencil_strokes_copybuf_free(); BKE_node_clipboard_clear(); BLF_exit(); #ifdef WITH_INTERNATIONAL BLF_free_unifont(); BLF_free_unifont_mono(); BLT_lang_free(); #endif ANIM_keyingset_infos_exit(); // free_txt_data(); #ifdef WITH_PYTHON /* option not to close python so we can use 'atexit' */ if (do_python && ((C == NULL) || CTX_py_init_get(C))) { /* XXX - old note */ /* before BKE_blender_free so py's gc happens while library still exists */ /* needed at least for a rare sigsegv that can happen in pydrivers */ /* Update for blender 2.5, move after BKE_blender_free because blender now holds references to PyObject's * so decref'ing them after python ends causes bad problems every time * the pyDriver bug can be fixed if it happens again we can deal with it then */ BPY_python_end(); } #else (void)do_python; #endif if (!G.background) { #ifdef WITH_OPENSUBDIV BKE_subsurf_osd_cleanup(); #endif GPU_global_buffer_pool_free(); GPU_free_unused_buffers(G_MAIN); GPU_exit(); } ED_file_exit(); /* for fsmenu */ UI_exit(); BKE_blender_userdef_data_free(&U, false); RNA_exit(); /* should be after BPY_python_end so struct python slots are cleared */ wm_ghost_exit(); CTX_free(C); #ifdef WITH_GAMEENGINE SYS_DeleteSystem(SYS_GetSystem()); #endif GHOST_DisposeSystemPaths(); DNA_sdna_current_free(); BLI_threadapi_exit(); /* No need to call this early, rather do it late so that other pieces of Blender using sound may exit cleanly, * see also T50676. */ BKE_sound_exit(); CLG_exit(); BKE_blender_atexit(); if (MEM_get_memory_blocks_in_use() != 0) { size_t mem_in_use = MEM_get_memory_in_use() + MEM_get_memory_in_use(); printf("Error: Not freed memory blocks: %u, total unfreed memory %f MB\n", MEM_get_memory_blocks_in_use(), (double)mem_in_use / 1024 / 1024); MEM_printmemlist(); } wm_autosave_delete(); BKE_tempdir_session_purge(); }
bool WM_init_game(bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win; ScrArea *sa; ARegion *ar = NULL; Scene *scene = CTX_data_scene(C); if (!scene) { /* XXX, this should not be needed. */ Main *bmain = CTX_data_main(C); scene = bmain->scene.first; } win = wm->windows.first; /* first to get a valid window */ if (win) CTX_wm_window_set(C, win); sa = BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_VIEW3D, 0); ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); /* if we have a valid 3D view */ if (sa && ar) { ARegion *arhide; CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); /* disable quad view */ if (ar->alignment == RGN_ALIGN_QSPLIT) WM_operator_name_call(C, "SCREEN_OT_region_quadview", WM_OP_EXEC_DEFAULT, NULL); /* toolbox, properties panel and header are hidden */ for (arhide = sa->regionbase.first; arhide; arhide = arhide->next) { if (arhide->regiontype != RGN_TYPE_WINDOW) { if (!(arhide->flag & RGN_FLAG_HIDDEN)) { ED_region_toggle_hidden(C, arhide); } } } /* full screen the area */ if (!sa->full) { ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED); } /* Fullscreen */ if ((scene->gm.playerflag & GAME_PLAYER_FULLSCREEN)) { WM_operator_name_call(C, "WM_OT_window_fullscreen_toggle", WM_OP_EXEC_DEFAULT, NULL); wm_get_screensize(&ar->winrct.xmax, &ar->winrct.ymax); ar->winx = ar->winrct.xmax + 1; ar->winy = ar->winrct.ymax + 1; } else { GHOST_RectangleHandle rect = GHOST_GetClientBounds(win->ghostwin); ar->winrct.ymax = GHOST_GetHeightRectangle(rect); ar->winrct.xmax = GHOST_GetWidthRectangle(rect); ar->winx = ar->winrct.xmax + 1; ar->winy = ar->winrct.ymax + 1; GHOST_DisposeRectangle(rect); } WM_operator_name_call(C, "VIEW3D_OT_game_start", WM_OP_EXEC_DEFAULT, NULL); BKE_sound_exit(); return true; } else { ReportTimerInfo *rti; BKE_report(&wm->reports, RPT_ERROR, "No valid 3D View found, game auto start is not possible"); /* After adding the report to the global list, reset the report timer. */ WM_event_remove_timer(wm, NULL, wm->reports.reporttimer); /* Records time since last report was added */ wm->reports.reporttimer = WM_event_add_timer(wm, CTX_wm_window(C), TIMER, 0.02); rti = MEM_callocN(sizeof(ReportTimerInfo), "ReportTimerInfo"); wm->reports.reporttimer->customdata = rti; return false; } }
bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) { if (!m_engineInitialized) { GPU_init(); bgl::InitExtensions(true); // get and set the preferences SYS_SystemHandle syshandle = SYS_GetSystem(); if (!syshandle) return false; // SYS_WriteCommandLineInt(syshandle, "fixedtime", 0); // SYS_WriteCommandLineInt(syshandle, "vertexarrays",1); GameData *gm= &m_startScene->gm; bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0); bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0); bool showPhysics = (gm->flag & GAME_SHOW_PHYSICS); SYS_WriteCommandLineInt(syshandle, "show_physics", showPhysics); bool fixed_framerate= (SYS_GetCommandLineInt(syshandle, "fixedtime", (gm->flag & GAME_ENABLE_ALL_FRAMES)) != 0); bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0); bool useLists = (SYS_GetCommandLineInt(syshandle, "displaylists", gm->flag & GAME_DISPLAY_LISTS) != 0) && GPU_display_list_support(); bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 1) != 0); bool restrictAnimFPS = (gm->flag & GAME_RESTRICT_ANIM_UPDATES) != 0; if (GLEW_ARB_multitexture && GLEW_VERSION_1_1) m_blendermat = (SYS_GetCommandLineInt(syshandle, "blender_material", 1) != 0); if (GPU_glsl_support()) m_blenderglslmat = (SYS_GetCommandLineInt(syshandle, "blender_glsl_material", 1) != 0); else if (m_globalSettings->matmode == GAME_MAT_GLSL) m_blendermat = false; // create the canvas, rasterizer and rendertools m_canvas = new GPG_Canvas(window); if (!m_canvas) return false; if (gm->vsync == VSYNC_ADAPTIVE) m_canvas->SetSwapInterval(-1); else m_canvas->SetSwapInterval((gm->vsync == VSYNC_ON) ? 1 : 0); m_canvas->Init(); if (gm->flag & GAME_SHOW_MOUSE) m_canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); //Don't use displaylists with VBOs //If auto starts using VBOs, make sure to check for that here if (useLists && gm->raster_storage != RAS_STORE_VBO) m_rasterizer = new RAS_ListRasterizer(m_canvas, false, gm->raster_storage); else m_rasterizer = new RAS_OpenGLRasterizer(m_canvas, gm->raster_storage); /* Stereo parameters - Eye Separation from the UI - stereomode from the command-line/UI */ m_rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) stereoMode); m_rasterizer->SetEyeSeparation(m_startScene->gm.eyeseparation); if (!m_rasterizer) goto initFailed; // create the inputdevices m_keyboard = new GPG_KeyboardDevice(); if (!m_keyboard) goto initFailed; m_mouse = new GPC_MouseDevice(); if (!m_mouse) goto initFailed; // create a networkdevice m_networkdevice = new NG_LoopBackNetworkDeviceInterface(); if (!m_networkdevice) goto initFailed; BKE_sound_init(m_maggie); // create a ketsjisystem (only needed for timing and stuff) m_kxsystem = new GPG_System (m_system); if (!m_kxsystem) goto initFailed; // create the ketsjiengine m_ketsjiengine = new KX_KetsjiEngine(m_kxsystem); // set the devices m_ketsjiengine->SetKeyboardDevice(m_keyboard); m_ketsjiengine->SetMouseDevice(m_mouse); m_ketsjiengine->SetNetworkDevice(m_networkdevice); m_ketsjiengine->SetCanvas(m_canvas); m_ketsjiengine->SetRasterizer(m_rasterizer); KX_KetsjiEngine::SetExitKey(ConvertKeyCode(gm->exitkey)); #ifdef WITH_PYTHON CValue::SetDeprecationWarnings(nodepwarnings); #else (void)nodepwarnings; #endif m_ketsjiengine->SetUseFixedTime(fixed_framerate); m_ketsjiengine->SetTimingDisplay(frameRate, profile, properties); m_ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS); //set the global settings (carried over if restart/load new files) m_ketsjiengine->SetGlobalSettings(m_globalSettings); m_engineInitialized = true; } return m_engineInitialized; initFailed: BKE_sound_exit(); delete m_kxsystem; delete m_networkdevice; delete m_mouse; delete m_keyboard; delete m_rasterizer; delete m_canvas; m_canvas = NULL; m_rasterizer = NULL; m_keyboard = NULL; m_mouse = NULL; m_networkdevice = NULL; m_kxsystem = NULL; return false; }