static int kbd_irq( int nIrqNum, void* pData, SysCallRegs_s* psRegs ) { int nCode; int nEFlg; int n; nCode = inb_p( 0x60 ); nEFlg = cli(); n = inb_p( 0x61 ); outb_p( n | 0x80, 0x61 ); outb_p( n & ~0x80, 0x61 ); nCode = ConvertKeyCode( nCode ); if ( 0 != nCode ) { g_sVolume.zBuffer[ atomic_inc_and_read( &g_sVolume.nInPos ) & 0xff ] = nCode; atomic_inc( &g_sVolume.nBytesReceived ); if ( -1 != g_sVolume.hWaitThread ) { wakeup_thread( g_sVolume.hWaitThread, false ); } } put_cpu_flags( nEFlg ); return( 0 ); }
static int ps2_interrupt( int nIrqNum, void* pData, SysCallRegs_s* psRegs ) { uint32 nFlg; int nData; PS2_Port_s* psPort = (PS2_Port_s*)pData; nFlg = spinlock_disable( &g_sLock ); if( ( inb( PS2_STATUS_REG ) & PS2_STS_OBF ) != PS2_STS_OBF ) { spinunlock_enable( &g_sLock, nFlg ); return( 0 ); } nData = inb( PS2_DATA_REG ); if( !psPort->bIsAux ) { if( nData == 0xfa ) { psPort->nAckReceived = 1; // Received ack } else if( nData == 0xfe ) { psPort->nAckReceived = -1; // Received noack } nData = ConvertKeyCode( nData ); } if( atomic_read( &psPort->nBytesReceived ) < PS2_BUF_SIZE ) { psPort->pBuffer[ atomic_inc_and_read( &psPort->nInPos ) % PS2_BUF_SIZE ] = nData; atomic_inc( &psPort->nBytesReceived ); wakeup_sem( psPort->hWait, false ); } spinunlock_enable( &g_sLock, nFlg ); return( 0 ); }
extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing) { /* context values */ struct wmWindow *win= CTX_wm_window(C); struct Scene *startscene= CTX_data_scene(C); struct Main* maggie1= CTX_data_main(C); RAS_Rect area_rect; area_rect.SetLeft(cam_frame->xmin); area_rect.SetBottom(cam_frame->ymin); area_rect.SetRight(cam_frame->xmax); area_rect.SetTop(cam_frame->ymax); int exitrequested = KX_EXIT_REQUEST_NO_REQUEST; Main* blenderdata = maggie1; char* startscenename = startscene->id.name+2; char pathname[FILE_MAXDIR+FILE_MAXFILE], oldsce[FILE_MAXDIR+FILE_MAXFILE]; STR_String exitstring = ""; BlendFileData *bfd= NULL; BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); BLI_strncpy(oldsce, G.main->name, sizeof(oldsce)); #ifdef WITH_PYTHON resetGamePythonPath(); // need this so running a second time wont use an old blendfiles path setGamePythonPath(G.main->name); // Acquire Python's GIL (global interpreter lock) // so we can safely run Python code and API calls PyGILState_STATE gilstate = PyGILState_Ensure(); PyObject *pyGlobalDict = PyDict_New(); /* python utility storage, spans blend file loading */ #endif bgl::InitExtensions(true); // VBO code for derived mesh is not compatible with BGE (couldn't find why), so disable int disableVBO = (U.gameflags & USER_DISABLE_VBO); U.gameflags |= USER_DISABLE_VBO; // Globals to be carried on over blender files GlobalSettings gs; gs.matmode= startscene->gm.matmode; gs.glslflag= startscene->gm.flag; do { View3D *v3d= CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); // get some preferences SYS_SystemHandle syshandle = SYS_GetSystem(); bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0); bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0); bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0); bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0); bool animation_record = (SYS_GetCommandLineInt(syshandle, "animation_record", 0) != 0); bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0); #ifdef WITH_PYTHON bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0); #endif bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0); bool mouse_state = startscene->gm.flag & GAME_SHOW_MOUSE; bool restrictAnimFPS = startscene->gm.flag & GAME_RESTRICT_ANIM_UPDATES; if(animation_record) usefixed= true; /* override since you's always want fixed time for sim recording */ // create the canvas, rasterizer and rendertools RAS_ICanvas* canvas = new KX_BlenderCanvas(win, area_rect, ar); // default mouse state set on render panel if (mouse_state) canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); else canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); RAS_IRenderTools* rendertools = new KX_BlenderRenderTools(); RAS_IRasterizer* rasterizer = NULL; if(displaylists) { if (GLEW_VERSION_1_1 && !novertexarrays) rasterizer = new RAS_ListRasterizer(canvas, true, true); else rasterizer = new RAS_ListRasterizer(canvas); } else if (GLEW_VERSION_1_1 && !novertexarrays) rasterizer = new RAS_VAOpenGLRasterizer(canvas, false); else rasterizer = new RAS_OpenGLRasterizer(canvas); // create the inputdevices KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice(); KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice(); // create a networkdevice NG_NetworkDeviceInterface* networkdevice = new NG_LoopBackNetworkDeviceInterface(); // // create a ketsji/blendersystem (only needed for timing and stuff) KX_BlenderSystem* kxsystem = new KX_BlenderSystem(); // create the ketsjiengine KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem); // set the devices ketsjiengine->SetKeyboardDevice(keyboarddevice); ketsjiengine->SetMouseDevice(mousedevice); ketsjiengine->SetNetworkDevice(networkdevice); ketsjiengine->SetCanvas(canvas); ketsjiengine->SetRenderTools(rendertools); ketsjiengine->SetRasterizer(rasterizer); ketsjiengine->SetUseFixedTime(usefixed); ketsjiengine->SetTimingDisplay(frameRate, profile, properties); ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS); KX_KetsjiEngine::SetExitKey(ConvertKeyCode(startscene->gm.exitkey)); //set the global settings (carried over if restart/load new files) ketsjiengine->SetGlobalSettings(&gs); #ifdef WITH_PYTHON CValue::SetDeprecationWarnings(nodepwarnings); #endif //lock frame and camera enabled - storing global values int tmp_lay= startscene->lay; Object *tmp_camera = startscene->camera; if (v3d->scenelock==0){ startscene->lay= v3d->lay; startscene->camera= v3d->camera; } // some blender stuff float camzoom; int draw_letterbox = 0; if(rv3d->persp==RV3D_CAMOB) { if(startscene->gm.framing.type == SCE_GAMEFRAMING_BARS) { /* Letterbox */ camzoom = 1.0f; draw_letterbox = 1; } else { camzoom = 1.0 / BKE_screen_view3d_zoom_to_fac(rv3d->camzoom); } } else { camzoom = 2.0; } ketsjiengine->SetDrawType(v3d->drawtype); ketsjiengine->SetCameraZoom(camzoom); // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME) { exitrequested = KX_EXIT_REQUEST_NO_REQUEST; if (bfd) BLO_blendfiledata_free(bfd); char basedpath[FILE_MAX]; // base the actuator filename with respect // to the original file working directory if (exitstring != "") strcpy(basedpath, exitstring.Ptr()); // load relative to the last loaded file, this used to be relative // to the first file but that makes no sense, relative paths in // blend files should be relative to that file, not some other file // that happened to be loaded first BLI_path_abs(basedpath, pathname); bfd = load_game_data(basedpath); // if it wasn't loaded, try it forced relative if (!bfd) { // just add "//" in front of it char temppath[242]; strcpy(temppath, "//"); strcat(temppath, basedpath); BLI_path_abs(temppath, pathname); bfd = load_game_data(temppath); } // if we got a loaded blendfile, proceed if (bfd) { blenderdata = bfd->main; startscenename = bfd->curscene->id.name + 2; if(blenderdata) { BLI_strncpy(G.main->name, blenderdata->name, sizeof(G.main->name)); BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); #ifdef WITH_PYTHON setGamePythonPath(G.main->name); #endif } } // else forget it, we can't find it else { exitrequested = KX_EXIT_REQUEST_QUIT_GAME; } } Scene *scene= bfd ? bfd->curscene : (Scene *)BLI_findstring(&blenderdata->scene, startscenename, offsetof(ID, name) + 2); if (scene) { int startFrame = scene->r.cfra; ketsjiengine->SetAnimRecordMode(animation_record, startFrame); // Quad buffered needs a special window. if(scene->gm.stereoflag == STEREO_ENABLED){ if (scene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) scene->gm.stereomode); rasterizer->SetEyeSeparation(scene->gm.eyeseparation); } rasterizer->SetBackColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 0.0f); } if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME) { if (rv3d->persp != RV3D_CAMOB) { ketsjiengine->EnableCameraOverride(startscenename); ketsjiengine->SetCameraOverrideUseOrtho((rv3d->persp == RV3D_ORTHO)); ketsjiengine->SetCameraOverrideProjectionMatrix(MT_CmMatrix4x4(rv3d->winmat)); ketsjiengine->SetCameraOverrideViewMatrix(MT_CmMatrix4x4(rv3d->viewmat)); if(rv3d->persp == RV3D_ORTHO) { ketsjiengine->SetCameraOverrideClipping(-v3d->far, v3d->far); } else { ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far); } ketsjiengine->SetCameraOverrideLens(v3d->lens); } // create a scene converter, create and convert the startingscene KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine); ketsjiengine->SetSceneConverter(sceneconverter); sceneconverter->addInitFromFrame=false; if (always_use_expand_framing) sceneconverter->SetAlwaysUseExpandFraming(true); bool usemat = false, useglslmat = false; if(GLEW_ARB_multitexture && GLEW_VERSION_1_1) usemat = true; if(GPU_glsl_support()) useglslmat = true; else if(gs.matmode == GAME_MAT_GLSL) usemat = false; if(usemat && (gs.matmode != GAME_MAT_TEXFACE)) sceneconverter->SetMaterials(true); if(useglslmat && (gs.matmode == GAME_MAT_GLSL)) sceneconverter->SetGLSLMaterials(true); KX_Scene* startscene = new KX_Scene(keyboarddevice, mousedevice, networkdevice, startscenename, scene, canvas); #ifdef WITH_PYTHON // some python things PyObject *gameLogic, *gameLogic_keys; setupGamePython(ketsjiengine, startscene, blenderdata, pyGlobalDict, &gameLogic, &gameLogic_keys, 0, NULL); #endif // WITH_PYTHON //initialize Dome Settings if(scene->gm.stereoflag == STEREO_DOME) 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); // initialize 3D Audio Settings AUD_I3DDevice* dev = AUD_get3DDevice(); if(dev) { dev->setSpeedOfSound(scene->audio.speed_of_sound); dev->setDopplerFactor(scene->audio.doppler_factor); dev->setDistanceModel(AUD_DistanceModel(scene->audio.distance_model)); } // from see blender.c: // FIXME: this version patching should really be part of the file-reading code, // but we still get too many unrelated data-corruption crashes otherwise... if (blenderdata->versionfile < 250) do_versions_ipos_to_animato(blenderdata); if (sceneconverter) { // convert and add scene sceneconverter->ConvertScene( startscene, rendertools, canvas); ketsjiengine->AddScene(startscene); // init the rasterizer rasterizer->Init(); // start the engine ketsjiengine->StartEngine(true); // Set the animation playback rate for ipo's and actions // the framerate below should patch with FPS macro defined in blendef.h // Could be in StartEngine set the framerate, we need the scene to do this ketsjiengine->SetAnimFrameRate(FPS); // the mainloop printf("\nBlender Game Engine Started\n"); while (!exitrequested) { // first check if we want to exit exitrequested = ketsjiengine->GetExitCode(); // kick the engine bool render = ketsjiengine->NextFrame(); if (render) { if(draw_letterbox) { // Clear screen to border color // We do this here since we set the canvas to be within the frames. This means the engine // itself is unaware of the extra space, so we clear the whole region for it. glClearColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 1.0f); glViewport(ar->winrct.xmin, ar->winrct.ymin, ar->winrct.xmax - ar->winrct.xmin, ar->winrct.ymax - ar->winrct.ymin); glClear(GL_COLOR_BUFFER_BIT); } // render the frame ketsjiengine->Render(); } wm_window_process_events_nosleep(); // test for the ESC key //XXX while (qtest()) while(wmEvent *event= (wmEvent *)win->queue.first) { short val = 0; //unsigned short event = 0; //XXX extern_qread(&val); if (keyboarddevice->ConvertBlenderEvent(event->type,event->val)) exitrequested = KX_EXIT_REQUEST_BLENDER_ESC; /* Coordinate conversion... where * should this really be? */ if (event->type==MOUSEMOVE) { /* Note, not nice! XXX 2.5 event hack */ val = event->x - ar->winrct.xmin; mousedevice->ConvertBlenderEvent(MOUSEX, val); val = ar->winy - (event->y - ar->winrct.ymin) - 1; mousedevice->ConvertBlenderEvent(MOUSEY, val); } else { mousedevice->ConvertBlenderEvent(event->type,event->val); } BLI_remlink(&win->queue, event); wm_event_free(event); } if(win != CTX_wm_window(C)) { exitrequested= KX_EXIT_REQUEST_OUTSIDE; /* window closed while bge runs */ } } printf("Blender Game Engine Finished\n"); exitstring = ketsjiengine->GetExitString(); gs = *(ketsjiengine->GetGlobalSettings()); // when exiting the mainloop #ifdef WITH_PYTHON // Clears the dictionary by hand: // This prevents, extra references to global variables // inside the GameLogic dictionary when the python interpreter is finalized. // which allows the scene to safely delete them :) // see: (space.c)->start_game //PyDict_Clear(PyModule_GetDict(gameLogic)); // Keep original items, means python plugins will autocomplete members PyObject *gameLogic_keys_new = PyDict_Keys(PyModule_GetDict(gameLogic)); const Py_ssize_t numitems= PyList_GET_SIZE(gameLogic_keys_new); Py_ssize_t listIndex; for (listIndex=0; listIndex < numitems; listIndex++) { PyObject* item = PyList_GET_ITEM(gameLogic_keys_new, listIndex); if (!PySequence_Contains(gameLogic_keys, item)) { PyDict_DelItem( PyModule_GetDict(gameLogic), item); } } Py_DECREF(gameLogic_keys_new); gameLogic_keys_new = NULL; #endif ketsjiengine->StopEngine(); #ifdef WITH_PYTHON exitGamePythonScripting(); #endif networkdevice->Disconnect(); } if (sceneconverter) { delete sceneconverter; sceneconverter = NULL; } #ifdef WITH_PYTHON Py_DECREF(gameLogic_keys); gameLogic_keys = NULL; #endif } //lock frame and camera enabled - restoring global values if (v3d->scenelock==0){ startscene->lay= tmp_lay; startscene->camera= tmp_camera; } if(exitrequested != KX_EXIT_REQUEST_OUTSIDE) { // set the cursor back to normal canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); } // clean up some stuff if (ketsjiengine) { delete ketsjiengine; ketsjiengine = NULL; } if (kxsystem) { delete kxsystem; kxsystem = NULL; } if (networkdevice) { delete networkdevice; networkdevice = NULL; } if (keyboarddevice) { delete keyboarddevice; keyboarddevice = NULL; } if (mousedevice) { delete mousedevice; mousedevice = NULL; } if (rasterizer) { delete rasterizer; rasterizer = NULL; } if (rendertools) { delete rendertools; rendertools = NULL; } if (canvas) { delete canvas; canvas = NULL; } // stop all remaining playing sounds AUD_getDevice()->stopAll(); } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME); if (!disableVBO) U.gameflags &= ~USER_DISABLE_VBO; if (bfd) BLO_blendfiledata_free(bfd); BLI_strncpy(G.main->name, oldsce, sizeof(G.main->name)); #ifdef WITH_PYTHON Py_DECREF(pyGlobalDict); // Release Python's GIL PyGILState_Release(gilstate); #endif }
extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing) { /* context values */ struct wmWindowManager *wm= CTX_wm_manager(C); struct wmWindow *win= CTX_wm_window(C); struct Scene *startscene= CTX_data_scene(C); struct Main* maggie1= CTX_data_main(C); RAS_Rect area_rect; area_rect.SetLeft(cam_frame->xmin); area_rect.SetBottom(cam_frame->ymin); area_rect.SetRight(cam_frame->xmax); area_rect.SetTop(cam_frame->ymax); int exitrequested = KX_EXIT_REQUEST_NO_REQUEST; Main* blenderdata = maggie1; char* startscenename = startscene->id.name+2; char pathname[FILE_MAXDIR+FILE_MAXFILE], oldsce[FILE_MAXDIR+FILE_MAXFILE]; STR_String exitstring = ""; BlendFileData *bfd= NULL; BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); BLI_strncpy(oldsce, G.main->name, sizeof(oldsce)); #ifdef WITH_PYTHON resetGamePythonPath(); // need this so running a second time wont use an old blendfiles path setGamePythonPath(G.main->name); // Acquire Python's GIL (global interpreter lock) // so we can safely run Python code and API calls PyGILState_STATE gilstate = PyGILState_Ensure(); PyObject *pyGlobalDict = PyDict_New(); /* python utility storage, spans blend file loading */ #endif bgl::InitExtensions(true); // VBO code for derived mesh is not compatible with BGE (couldn't find why), so disable int disableVBO = (U.gameflags & USER_DISABLE_VBO); U.gameflags |= USER_DISABLE_VBO; // Globals to be carried on over blender files GlobalSettings gs; gs.matmode= startscene->gm.matmode; gs.glslflag= startscene->gm.flag; do { View3D *v3d= CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); // get some preferences SYS_SystemHandle syshandle = SYS_GetSystem(); bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0); bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0); bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0); bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0); bool animation_record = (SYS_GetCommandLineInt(syshandle, "animation_record", 0) != 0); bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0) && GPU_display_list_support(); #ifdef WITH_PYTHON bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0); #endif // bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0); bool mouse_state = (startscene->gm.flag & GAME_SHOW_MOUSE) != 0; bool restrictAnimFPS = (startscene->gm.flag & GAME_RESTRICT_ANIM_UPDATES) != 0; short drawtype = v3d->drawtype; /* we do not support material mode in game engine, force change to texture mode */ if (drawtype == OB_MATERIAL) drawtype = OB_TEXTURE; if (animation_record) usefixed= false; /* override since you don't want to run full-speed for sim recording */ // create the canvas and rasterizer RAS_ICanvas* canvas = new KX_BlenderCanvas(wm, win, area_rect, ar); // default mouse state set on render panel if (mouse_state) canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); else canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); // Setup vsync int previous_vsync = 0; canvas->GetSwapInterval(previous_vsync); if (startscene->gm.vsync == VSYNC_ADAPTIVE) canvas->SetSwapInterval(-1); else canvas->SetSwapInterval((startscene->gm.vsync == VSYNC_ON) ? 1 : 0); RAS_IRasterizer* rasterizer = NULL; //Don't use displaylists with VBOs //If auto starts using VBOs, make sure to check for that here if (displaylists && startscene->gm.raster_storage != RAS_STORE_VBO) rasterizer = new RAS_ListRasterizer(canvas, true, startscene->gm.raster_storage); else rasterizer = new RAS_OpenGLRasterizer(canvas, startscene->gm.raster_storage); RAS_IRasterizer::MipmapOption mipmapval = rasterizer->GetMipmapping(); // create the inputdevices KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice(); KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice(); // create a networkdevice NG_NetworkDeviceInterface* networkdevice = new NG_LoopBackNetworkDeviceInterface(); // // create a ketsji/blendersystem (only needed for timing and stuff) KX_BlenderSystem* kxsystem = new KX_BlenderSystem(); // create the ketsjiengine KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem); // set the devices ketsjiengine->SetKeyboardDevice(keyboarddevice); ketsjiengine->SetMouseDevice(mousedevice); ketsjiengine->SetNetworkDevice(networkdevice); ketsjiengine->SetCanvas(canvas); ketsjiengine->SetRasterizer(rasterizer); ketsjiengine->SetUseFixedTime(usefixed); ketsjiengine->SetTimingDisplay(frameRate, profile, properties); ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS); KX_KetsjiEngine::SetExitKey(ConvertKeyCode(startscene->gm.exitkey)); //set the global settings (carried over if restart/load new files) ketsjiengine->SetGlobalSettings(&gs); #ifdef WITH_PYTHON CValue::SetDeprecationWarnings(nodepwarnings); #endif //lock frame and camera enabled - storing global values int tmp_lay= startscene->lay; Object *tmp_camera = startscene->camera; if (v3d->scenelock==0) { startscene->lay= v3d->lay; startscene->camera= v3d->camera; } // some blender stuff float camzoom; int draw_letterbox = 0; if (rv3d->persp==RV3D_CAMOB) { if (startscene->gm.framing.type == SCE_GAMEFRAMING_BARS) { /* Letterbox */ camzoom = 1.0f; draw_letterbox = 1; } else { camzoom = 1.0f / BKE_screen_view3d_zoom_to_fac(rv3d->camzoom); } } else { camzoom = 2.0; } rasterizer->SetDrawingMode(drawtype); ketsjiengine->SetCameraZoom(camzoom); // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME) { exitrequested = KX_EXIT_REQUEST_NO_REQUEST; if (bfd) BLO_blendfiledata_free(bfd); char basedpath[FILE_MAX]; // base the actuator filename with respect // to the original file working directory if (exitstring != "") BLI_strncpy(basedpath, exitstring.ReadPtr(), sizeof(basedpath)); // load relative to the last loaded file, this used to be relative // to the first file but that makes no sense, relative paths in // blend files should be relative to that file, not some other file // that happened to be loaded first BLI_path_abs(basedpath, pathname); bfd = load_game_data(basedpath); // if it wasn't loaded, try it forced relative if (!bfd) { // just add "//" in front of it char temppath[FILE_MAX] = "//"; BLI_strncpy(temppath + 2, basedpath, FILE_MAX - 2); BLI_path_abs(temppath, pathname); bfd = load_game_data(temppath); } // if we got a loaded blendfile, proceed if (bfd) { blenderdata = bfd->main; startscenename = bfd->curscene->id.name + 2; if (blenderdata) { BLI_strncpy(G.main->name, blenderdata->name, sizeof(G.main->name)); BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); #ifdef WITH_PYTHON setGamePythonPath(G.main->name); #endif } } // else forget it, we can't find it else { exitrequested = KX_EXIT_REQUEST_QUIT_GAME; } } Scene *scene= bfd ? bfd->curscene : (Scene *)BLI_findstring(&blenderdata->scene, startscenename, offsetof(ID, name) + 2); if (scene) { int startFrame = scene->r.cfra; ketsjiengine->SetAnimRecordMode(animation_record, startFrame); // Quad buffered needs a special window. if (scene->gm.stereoflag == STEREO_ENABLED) { if (scene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) scene->gm.stereomode); rasterizer->SetEyeSeparation(scene->gm.eyeseparation); } rasterizer->SetBackColor(scene->gm.framing.col); } if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME) { if (rv3d->persp != RV3D_CAMOB) { ketsjiengine->EnableCameraOverride(startscenename); ketsjiengine->SetCameraOverrideUseOrtho((rv3d->persp == RV3D_ORTHO)); ketsjiengine->SetCameraOverrideProjectionMatrix(MT_CmMatrix4x4(rv3d->winmat)); ketsjiengine->SetCameraOverrideViewMatrix(MT_CmMatrix4x4(rv3d->viewmat)); ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far); ketsjiengine->SetCameraOverrideLens(v3d->lens); } // create a scene converter, create and convert the startingscene KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine); ketsjiengine->SetSceneConverter(sceneconverter); if (always_use_expand_framing) sceneconverter->SetAlwaysUseExpandFraming(true); bool usemat = false, useglslmat = false; if (GLEW_ARB_multitexture && GLEW_VERSION_1_1) usemat = true; if (GPU_glsl_support()) useglslmat = true; else if (gs.matmode == GAME_MAT_GLSL) usemat = false; if (usemat) sceneconverter->SetMaterials(true); if (useglslmat && (gs.matmode == GAME_MAT_GLSL)) sceneconverter->SetGLSLMaterials(true); if (scene->gm.flag & GAME_NO_MATERIAL_CACHING) sceneconverter->SetCacheMaterials(false); KX_Scene* startscene = new KX_Scene(keyboarddevice, mousedevice, networkdevice, startscenename, scene, canvas); #ifdef WITH_PYTHON // some python things PyObject *gameLogic, *gameLogic_keys; setupGamePython(ketsjiengine, startscene, blenderdata, pyGlobalDict, &gameLogic, &gameLogic_keys, 0, NULL); #endif // WITH_PYTHON //initialize Dome Settings if (scene->gm.stereoflag == STEREO_DOME) 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); // initialize 3D Audio Settings AUD_I3DDevice* dev = AUD_get3DDevice(); if (dev) { dev->setSpeedOfSound(scene->audio.speed_of_sound); dev->setDopplerFactor(scene->audio.doppler_factor); dev->setDistanceModel(AUD_DistanceModel(scene->audio.distance_model)); } // from see blender.c: // FIXME: this version patching should really be part of the file-reading code, // but we still get too many unrelated data-corruption crashes otherwise... if (blenderdata->versionfile < 250) do_versions_ipos_to_animato(blenderdata); if (sceneconverter) { // convert and add scene sceneconverter->ConvertScene( startscene, rasterizer, canvas); ketsjiengine->AddScene(startscene); // init the rasterizer rasterizer->Init(); // start the engine ketsjiengine->StartEngine(true); // Set the animation playback rate for ipo's and actions // the framerate below should patch with FPS macro defined in blendef.h // Could be in StartEngine set the framerate, we need the scene to do this ketsjiengine->SetAnimFrameRate(FPS); #ifdef WITH_PYTHON char *python_main = NULL; pynextframestate.state = NULL; pynextframestate.func = NULL; python_main = KX_GetPythonMain(scene); // the mainloop printf("\nBlender Game Engine Started\n"); if (python_main) { char *python_code = KX_GetPythonCode(blenderdata, python_main); if (python_code) { ketsjinextframestate.ketsjiengine = ketsjiengine; ketsjinextframestate.C = C; ketsjinextframestate.win = win; ketsjinextframestate.scene = scene; ketsjinextframestate.ar = ar; ketsjinextframestate.keyboarddevice = keyboarddevice; ketsjinextframestate.mousedevice = mousedevice; ketsjinextframestate.draw_letterbox = draw_letterbox; pynextframestate.state = &ketsjinextframestate; pynextframestate.func = &BL_KetsjiPyNextFrame; printf("Yielding control to Python script '%s'...\n", python_main); PyRun_SimpleString(python_code); printf("Exit Python script '%s'\n", python_main); MEM_freeN(python_code); } } else #endif /* WITH_PYTHON */ { while (!exitrequested) { exitrequested = BL_KetsjiNextFrame(ketsjiengine, C, win, scene, ar, keyboarddevice, mousedevice, draw_letterbox); } } printf("Blender Game Engine Finished\n"); exitstring = ketsjiengine->GetExitString(); #ifdef WITH_PYTHON if (python_main) MEM_freeN(python_main); #endif /* WITH_PYTHON */ gs = *(ketsjiengine->GetGlobalSettings()); // when exiting the mainloop #ifdef WITH_PYTHON // Clears the dictionary by hand: // This prevents, extra references to global variables // inside the GameLogic dictionary when the python interpreter is finalized. // which allows the scene to safely delete them :) // see: (space.c)->start_game //PyDict_Clear(PyModule_GetDict(gameLogic)); // Keep original items, means python plugins will autocomplete members PyObject *gameLogic_keys_new = PyDict_Keys(PyModule_GetDict(gameLogic)); const Py_ssize_t numitems= PyList_GET_SIZE(gameLogic_keys_new); Py_ssize_t listIndex; for (listIndex=0; listIndex < numitems; listIndex++) { PyObject *item = PyList_GET_ITEM(gameLogic_keys_new, listIndex); if (!PySequence_Contains(gameLogic_keys, item)) { PyDict_DelItem( PyModule_GetDict(gameLogic), item); } } Py_DECREF(gameLogic_keys_new); gameLogic_keys_new = NULL; #endif ketsjiengine->StopEngine(); #ifdef WITH_PYTHON exitGamePythonScripting(); #endif networkdevice->Disconnect(); } if (sceneconverter) { delete sceneconverter; sceneconverter = NULL; } #ifdef WITH_PYTHON Py_DECREF(gameLogic_keys); gameLogic_keys = NULL; #endif } //lock frame and camera enabled - restoring global values if (v3d->scenelock==0) { startscene->lay= tmp_lay; startscene->camera= tmp_camera; } if (exitrequested != KX_EXIT_REQUEST_OUTSIDE) { // set the cursor back to normal canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); // set mipmap setting back to its original value rasterizer->SetMipmapping(mipmapval); } // clean up some stuff if (ketsjiengine) { delete ketsjiengine; ketsjiengine = NULL; } if (kxsystem) { delete kxsystem; kxsystem = NULL; } if (networkdevice) { delete networkdevice; networkdevice = NULL; } if (keyboarddevice) { delete keyboarddevice; keyboarddevice = NULL; } if (mousedevice) { delete mousedevice; mousedevice = NULL; } if (rasterizer) { delete rasterizer; rasterizer = NULL; } if (canvas) { canvas->SetSwapInterval(previous_vsync); // Set the swap interval back delete canvas; canvas = NULL; } // stop all remaining playing sounds AUD_getDevice()->stopAll(); } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME); if (!disableVBO) U.gameflags &= ~USER_DISABLE_VBO; if (bfd) BLO_blendfiledata_free(bfd); BLI_strncpy(G.main->name, oldsce, sizeof(G.main->name)); #ifdef WITH_PYTHON Py_DECREF(pyGlobalDict); // Release Python's GIL PyGILState_Release(gilstate); #endif }
void BL_ConvertSensors(struct Object* blenderobject, class KX_GameObject* gameobj, SCA_LogicManager* logicmgr, KX_Scene* kxscene, KX_KetsjiEngine* kxengine, int activeLayerBitInfo, bool isInActiveLayer, RAS_ICanvas* canvas, KX_BlenderSceneConverter* converter ) { int executePriority = 0; int uniqueint = 0; int count = 0; bSensor* sens = (bSensor*)blenderobject->sensors.first; bool pos_pulsemode = false; bool neg_pulsemode = false; int skipped_ticks = 0; bool invert = false; bool level = false; bool tap = false; while (sens) { sens = sens->next; count++; } gameobj->ReserveSensor(count); sens = (bSensor*)blenderobject->sensors.first; while (sens) { if (!(sens->flag & SENS_DEACTIVATE)) { SCA_ISensor* gamesensor=NULL; /* All sensors have a pulse toggle, skipped ticks parameter, and invert field. */ /* These are extracted here, and set when the sensor is added to the */ /* list. */ pos_pulsemode = (sens->pulse & SENS_PULSE_REPEAT)!=0; neg_pulsemode = (sens->pulse & SENS_NEG_PULSE_MODE)!=0; skipped_ticks = sens->freq; invert = !(sens->invert == 0); level = !(sens->level == 0); tap = !(sens->tap == 0); switch (sens->type) { case SENS_ALWAYS: { SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR); if (eventmgr) { gamesensor = new SCA_AlwaysSensor(eventmgr, gameobj); } break; } case SENS_DELAY: { // we can reuse the Always event manager for the delay sensor SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR); if (eventmgr) { bDelaySensor* delaysensor = (bDelaySensor*)sens->data; gamesensor = new SCA_DelaySensor(eventmgr, gameobj, delaysensor->delay, delaysensor->duration, (delaysensor->flag & SENS_DELAY_REPEAT) != 0); } break; } case SENS_COLLISION: { SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR); if (eventmgr) { // collision sensor can sense both materials and properties. bool bFindMaterial = false, bCollisionPulse = false; bCollisionSensor* blendercollisionsensor = (bCollisionSensor*)sens->data; bFindMaterial = (blendercollisionsensor->mode & SENS_COLLISION_MATERIAL); bCollisionPulse = (blendercollisionsensor->mode & SENS_COLLISION_PULSE); const std::string touchPropOrMatName = bFindMaterial ? blendercollisionsensor->materialName : blendercollisionsensor->name; if (gameobj->GetPhysicsController()) { gamesensor = new KX_CollisionSensor(eventmgr, gameobj, bFindMaterial, bCollisionPulse, touchPropOrMatName); } } break; } case SENS_MESSAGE: { SCA_EventManager *eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR); bMessageSensor* msgSens = (bMessageSensor*) sens->data; /* Get our NetworkScene */ KX_NetworkMessageScene *NetworkScene = kxscene->GetNetworkMessageScene(); /* filter on the incoming subjects, might be empty */ const std::string subject = msgSens->subject; gamesensor = new KX_NetworkMessageSensor( eventmgr, // our eventmanager NetworkScene, // our NetworkScene gameobj, // the sensor controlling object subject); // subject to filter on break; } case SENS_NEAR: { SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR); if (eventmgr) { bNearSensor* blendernearsensor = (bNearSensor*)sens->data; const std::string nearpropertyname = (char *)blendernearsensor->name; //DT_ShapeHandle shape = DT_Sphere(0.0); // this sumoObject is not deleted by a gameobj, so delete it ourself // later (memleaks)! float radius = blendernearsensor->dist; const MT_Vector3& wpos = gameobj->NodeGetWorldPosition(); bool bFindMaterial = false; PHY_IPhysicsController* physCtrl = kxscene->GetPhysicsEnvironment()->CreateSphereController(radius,wpos); //will be done in KX_CollisionEventManager::RegisterSensor() //if (isInActiveLayer) // kxscene->GetPhysicsEnvironment()->addSensor(physCtrl); gamesensor = new KX_NearSensor(eventmgr,gameobj, blendernearsensor->dist, blendernearsensor->resetdist, bFindMaterial, nearpropertyname, physCtrl); } break; } case SENS_KEYBOARD: { /* temporary input device, for converting the code for the keyboard sensor */ bKeyboardSensor* blenderkeybdsensor = (bKeyboardSensor*)sens->data; SCA_KeyboardManager* eventmgr = (SCA_KeyboardManager*) logicmgr->FindEventManager(SCA_EventManager::KEYBOARD_EVENTMGR); if (eventmgr) { gamesensor = new SCA_KeyboardSensor(eventmgr, ConvertKeyCode(blenderkeybdsensor->key), ConvertKeyCode(blenderkeybdsensor->qual), ConvertKeyCode(blenderkeybdsensor->qual2), (blenderkeybdsensor->type == SENS_ALL_KEYS), blenderkeybdsensor->targetName, blenderkeybdsensor->toggleName, gameobj, KX_KetsjiEngine::GetExitKey()); // blenderkeybdsensor->pad); } break; } case SENS_MOUSE: { int keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_NODEF; int trackfocus = 0; bMouseSensor *bmouse = (bMouseSensor *)sens->data; /* There are two main types of mouse sensors. If there is * no focus-related behavior requested, we can make do * with a basic sensor. This cuts down memory usage and * gives a slight performance gain. */ SCA_MouseManager *eventmgr = (SCA_MouseManager*) logicmgr->FindEventManager(SCA_EventManager::MOUSE_EVENTMGR); if (eventmgr) { /* Determine key mode. There is at most one active mode. */ switch (bmouse->type) { case BL_SENS_MOUSE_LEFT_BUTTON: keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_LEFTBUTTON; break; case BL_SENS_MOUSE_MIDDLE_BUTTON: keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MIDDLEBUTTON; break; case BL_SENS_MOUSE_RIGHT_BUTTON: keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_RIGHTBUTTON; break; case BL_SENS_MOUSE_WHEEL_UP: keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_WHEELUP; break; case BL_SENS_MOUSE_WHEEL_DOWN: keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_WHEELDOWN; break; case BL_SENS_MOUSE_MOVEMENT: keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MOVEMENT; break; case BL_SENS_MOUSE_MOUSEOVER: trackfocus = 1; break; case BL_SENS_MOUSE_MOUSEOVER_ANY: trackfocus = 2; break; default: ; /* error */ } /* initial mouse position */ int startx = canvas->GetWidth()/2; int starty = canvas->GetHeight()/2; if (!trackfocus) { /* plain, simple mouse sensor */ gamesensor = new SCA_MouseSensor(eventmgr, startx,starty, keytype, gameobj); } else { /* give us a focus-aware sensor */ bool bFindMaterial = (bmouse->mode & SENS_COLLISION_MATERIAL); bool bXRay = (bmouse->flag & SENS_RAY_XRAY); std::string checkname = (bFindMaterial? bmouse->matname : bmouse->propname); gamesensor = new KX_MouseFocusSensor(eventmgr, startx, starty, keytype, trackfocus, (bmouse->flag & SENS_MOUSE_FOCUS_PULSE) ? true:false, checkname, bFindMaterial, bXRay, kxscene, kxengine, gameobj); } } break; } case SENS_PROPERTY: { bPropertySensor* blenderpropsensor = (bPropertySensor*) sens->data; SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR); if (eventmgr) { std::string propname=blenderpropsensor->name; std::string propval=blenderpropsensor->value; std::string propmaxval=blenderpropsensor->maxvalue; SCA_PropertySensor::KX_PROPSENSOR_TYPE propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NODEF; /* Better do an explicit conversion here! (was implicit */ /* before...) */ switch (blenderpropsensor->type) { case SENS_PROP_EQUAL: propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EQUAL; break; case SENS_PROP_NEQUAL: propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NOTEQUAL; break; case SENS_PROP_INTERVAL: propchecktype = SCA_PropertySensor::KX_PROPSENSOR_INTERVAL; break; case SENS_PROP_CHANGED: propchecktype = SCA_PropertySensor::KX_PROPSENSOR_CHANGED; break; case SENS_PROP_EXPRESSION: propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EXPRESSION; /* error */ break; case SENS_PROP_LESSTHAN: propchecktype = SCA_PropertySensor::KX_PROPSENSOR_LESSTHAN; break; case SENS_PROP_GREATERTHAN: propchecktype = SCA_PropertySensor::KX_PROPSENSOR_GREATERTHAN; break; default: ; /* error */ } gamesensor = new SCA_PropertySensor(eventmgr,gameobj,propname,propval,propmaxval,propchecktype); } break; } case SENS_ACTUATOR: { bActuatorSensor* blenderactsensor = (bActuatorSensor*) sens->data; // we will reuse the property event manager, there is nothing special with this sensor SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::ACTUATOR_EVENTMGR); if (eventmgr) { std::string propname=blenderactsensor->name; gamesensor = new SCA_ActuatorSensor(eventmgr,gameobj,propname); } break; } case SENS_ARMATURE: { bArmatureSensor* blenderarmsensor = (bArmatureSensor*) sens->data; // we will reuse the property event manager, there is nothing special with this sensor SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR); if (eventmgr) { std::string bonename=blenderarmsensor->posechannel; std::string constraintname=blenderarmsensor->constraint; gamesensor = new KX_ArmatureSensor(eventmgr,gameobj,bonename,constraintname, blenderarmsensor->type, blenderarmsensor->value); } break; } case SENS_RADAR: { SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR); if (eventmgr) { bRadarSensor* blenderradarsensor = (bRadarSensor*) sens->data; const std::string radarpropertyname = blenderradarsensor->name; int radaraxis = blenderradarsensor->axis; MT_Scalar coneheight = blenderradarsensor->range; // janco: the angle was doubled, so should I divide the factor in 2 // or the blenderradarsensor->angle? // nzc: the angle is the opening angle. We need to init with // the axis-hull angle,so /2.0. MT_Scalar factor = tan(blenderradarsensor->angle * 0.5f); //MT_Scalar coneradius = coneheight * (factor / 2); MT_Scalar coneradius = coneheight * factor; // this sumoObject is not deleted by a gameobj, so delete it ourself // later (memleaks)! MT_Scalar smallmargin = 0.0; MT_Scalar largemargin = 0.0; bool bFindMaterial = false; PHY_IPhysicsController* ctrl = kxscene->GetPhysicsEnvironment()->CreateConeController((float)coneradius, (float)coneheight); gamesensor = new KX_RadarSensor( eventmgr, gameobj, ctrl, coneradius, coneheight, radaraxis, smallmargin, largemargin, bFindMaterial, radarpropertyname); } break; } case SENS_RAY: { bRaySensor* blenderraysensor = (bRaySensor*) sens->data; //blenderradarsensor->angle; SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR); if (eventmgr) { bool bFindMaterial = (blenderraysensor->mode & SENS_COLLISION_MATERIAL); bool bXRay = (blenderraysensor->mode & SENS_RAY_XRAY); std::string checkname = (bFindMaterial? blenderraysensor->matname : blenderraysensor->propname); // don't want to get rays of length 0.0 or so double distance = (blenderraysensor->range < 0.01f ? 0.01f : blenderraysensor->range); int axis = blenderraysensor->axisflag; int mask = blenderraysensor->mask; gamesensor = new KX_RaySensor(eventmgr, gameobj, checkname, bFindMaterial, bXRay, distance, axis, mask, kxscene); } break; } case SENS_RANDOM: { bRandomSensor* blenderrndsensor = (bRandomSensor*) sens->data; // some files didn't write randomsensor, avoid crash now for NULL ptr's if (blenderrndsensor) { SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR); if (eventmgr) { int randomSeed = blenderrndsensor->seed; if (randomSeed == 0) { randomSeed = (int)(kxengine->GetRealTime()*100000.0); randomSeed ^= (intptr_t)blenderrndsensor; } gamesensor = new SCA_RandomSensor(eventmgr, gameobj, randomSeed); } } break; } case SENS_MOVEMENT: { bMovementSensor *blendermovsensor = (bMovementSensor *)sens->data; // some files didn't write movementsensor, avoid crash now for NULL ptr's if (blendermovsensor) { SCA_EventManager *eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR); if (eventmgr) { bool localflag = (blendermovsensor->localflag & SENS_MOVEMENT_LOCAL); int axis = blendermovsensor->axisflag; float threshold = blendermovsensor->threshold; gamesensor = new KX_MovementSensor(eventmgr, gameobj, axis, localflag, threshold); } } break; } case SENS_JOYSTICK: { int joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_NODEF; bJoystickSensor* bjoy = (bJoystickSensor*) sens->data; SCA_JoystickManager *eventmgr = (SCA_JoystickManager*) logicmgr->FindEventManager(SCA_EventManager::JOY_EVENTMGR); if (eventmgr) { int axis =0; int axisf =0; int button =0; int prec =0; switch (bjoy->type) { case SENS_JOY_AXIS: axis = bjoy->axis; axisf = bjoy->axisf; prec = bjoy->precision; joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_AXIS; break; case SENS_JOY_BUTTON: button = bjoy->button; joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_BUTTON; break; case SENS_JOY_AXIS_SINGLE: axis = bjoy->axis_single; prec = bjoy->precision; joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_AXIS_SINGLE; break; case SENS_JOY_SHOULDER_TRIGGER: axis = bjoy->axis_single; prec = bjoy->precision; joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_SHOULDER_TRIGGER; break; default: CM_Error("bad case statement"); break; } gamesensor = new SCA_JoystickSensor( eventmgr, gameobj, bjoy->joyindex, joysticktype, axis,axisf, prec, button, (bjoy->flag & SENS_JOY_ANY_EVENT)); } else { CM_Error("problem finding the event manager"); } break; } default: { } } if (gamesensor) { gamesensor->SetExecutePriority(executePriority++); std::string uniquename = sens->name; uniquename += "#SENS#"; uniqueint++; CIntValue* uniqueval = new CIntValue(uniqueint); uniquename += uniqueval->GetText(); uniqueval->Release(); /* Conversion succeeded, so we can set the generic props here. */ gamesensor->SetPulseMode(pos_pulsemode, neg_pulsemode, skipped_ticks); gamesensor->SetInvert(invert); gamesensor->SetLevel(level); gamesensor->SetTap(tap); gamesensor->SetName(sens->name); gamesensor->SetLogicManager(logicmgr); gameobj->AddSensor(gamesensor); // only register to manager if it's in an active layer // Make registration dynamic: only when sensor is activated //if (isInActiveLayer) // gamesensor->RegisterToManager(); gamesensor->ReserveController(sens->totlinks); for (int i=0;i<sens->totlinks;i++) { bController* linkedcont = (bController*) sens->links[i]; if (linkedcont) { // If the controller is deactived doesn't register it if (!(linkedcont->flag & CONT_DEACTIVATE)) { SCA_IController* gamecont = converter->FindGameController(linkedcont); if (gamecont) { logicmgr->RegisterToSensor(gamecont,gamesensor); } else { CM_Warning("Warning, sensor \"" << sens->name << "\" could not find its controller (link " << (i + 1) << " of " << sens->totlinks << ") from object \"" << blenderobject->id.name+2 << "\". There has been an error converting the blender controller for the game engine, " << "logic may be incorrect"); } } } else { CM_Warning("Warning, sensor \"" << sens->name << "\" has lost a link to a controller (link " << (i + 1) << " of " << sens->totlinks << ") from object \"" << blenderobject->id.name+2 << "\". Possible causes are partially appended objects or an error reading the file, " << "logic may be incorrect"); } } // special case: Keyboard sensor with no link // this combination is usually used for key logging. if (sens->type == SENS_KEYBOARD && sens->totlinks == 0) { // Force the registration so that the sensor runs gamesensor->IncLink(); } // done with gamesensor gamesensor->Release(); } } sens=sens->next; } }
// // WndProc // Handles the main message loop's events/messages //----------------------------------------------------------------------------- LRESULT CALLBACK CPUTWindowWin::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { CPUTEventHandledCode handledCode = CPUT_EVENT_UNHANDLED; LRESULT res; switch (message) { case WM_COMMAND: int wmId, wmEvent; wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // handle any menu item events here // see reference code in file history for examples break; case WM_KEYDOWN: if(mCPUT) { CPUTKey key = ConvertSpecialKeyCode(wParam, lParam); if(KEY_NONE!=key) { handledCode = mCPUT->CPUTHandleKeyboardEvent( key ); } } break; case WM_CHAR: // WM_KEYDOWN: gives you EVERY key - including shifts/etc if(mCPUT) { CPUTKey key = ConvertKeyCode(wParam, lParam); if(KEY_NONE!=key) { handledCode = mCPUT->CPUTHandleKeyboardEvent( key ); } } break; case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK: // handle double-click events break; case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_MOUSEMOVE: if(mCPUT) { CPUTMouseState state = ConvertMouseState(wParam); short xPos = LOWORD(lParam); short yPos = HIWORD(lParam); handledCode = mCPUT->CPUTHandleMouseEvent(xPos, yPos, 0, state); } break; case WM_MOUSEWHEEL: if(mCPUT) { // get mouse position short xPos = LOWORD(lParam); short yPos = HIWORD(lParam); // get wheel delta int wheel = GET_WHEEL_DELTA_WPARAM(wParam); // one 'click' handledCode = mCPUT->CPUTHandleMouseEvent(xPos, yPos, wheel, CPUT_MOUSE_WHEEL); } return 0; break; case WM_PAINT: PAINTSTRUCT ps; HDC hdc; hdc = BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); break; case WM_SIZING: case WM_MOVING: case WM_ERASEBKGND: // overriding this to do nothing avoids flicker and // the expense of re-creating tons of gfx contexts as it resizes break; //case WM_ACTIVATE: // check for maximize/minimize // break; case WM_SIZE: int width, height; height = HIWORD(lParam); width = LOWORD(lParam); RECT windowRect; if(0==GetClientRect(hWnd, &windowRect)) // this gets the client area inside the window frame *excluding* frames/menu bar/etc break; width = windowRect.right - windowRect.left; height = windowRect.bottom - windowRect.top; if(mCPUT) { // maximize/minimize effect if( (SIZE_MAXIMIZED == wParam) || (SIZE_MINIMIZED==wParam) ) { // resize for new max/min size mCPUT->ResizeWindow(width,height); mbMaxMinFullScreen = true; } else if(SIZE_RESTORED == wParam) { if(true == mbMaxMinFullScreen) { // resize for new max/min size mCPUT->ResizeWindow(width,height); mbMaxMinFullScreen = false; } else { // do a stretch-blit while actively sizing by just rendering to un-resized back buffer mCPUT->ResizeWindowSoft(width, height); } } } break; case WM_EXITSIZEMOVE: // update the system's size and make callback if(mCPUT) { RECT windowRect; if(0==GetClientRect(hWnd, &windowRect)) // this gets the client area inside the window frame *excluding* frames/menu bar/etc break; width = windowRect.right - windowRect.left; height = windowRect.bottom - windowRect.top; mCPUT->ResizeWindow(width,height); } break; case WM_DESTROY: // time to shut down the system PostQuitMessage(0); break; default: // we don't handle it - pass it on thru to parent res = DefWindowProc(hWnd, message, wParam, lParam); return res; } // translate handled code if(CPUT_EVENT_HANDLED == handledCode) { return 1; } return 0; }
bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) { if (!m_engineInitialized) { GPU_extensions_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; 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; 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: 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; }
// Main message pump //----------------------------------------------------------------------------- int CPUTWindowX::StartMessageLoop() { bool fRunning = true; XEvent event; while (fRunning) { if (XPending(pDisplay) > 0) { XNextEvent((pDisplay), &event); switch(event.type) { case KeyPress: if(mCPUT) { CPUTKey key = ConvertKeyCode(&event.xkey); CPUTKeyState state = CPUT_KEY_DOWN; if(key != KEY_NONE) { CPUTEventHandledCode handledCode; handledCode = mCPUT->CPUTHandleKeyboardEvent( key, state ); } } break; case KeyRelease: if(mCPUT) { CPUTKey key = ConvertKeyCode(&event.xkey); CPUTKeyState state = CPUT_KEY_UP; if(key != KEY_NONE) { CPUTEventHandledCode handledCode; handledCode = mCPUT->CPUTHandleKeyboardEvent( key, state ); } } break; case CreateNotify: break; case DestroyNotify: fRunning = false; break; case ClientMessage: if (event.xclient.data.l[0] == wmDeleteMessage) { fRunning = false; } break; case ButtonPress: if (mCPUT) { CPUTEventHandledCode handledCode; CPUTMouseState state = ConvertMouseState(&event.xbutton); short xPos = event.xbutton.x; short yPos = event.xbutton.y; handledCode = mCPUT->CPUTHandleMouseEvent(xPos, yPos, 0, state); } break; case ButtonRelease: if (mCPUT) { CPUTEventHandledCode handledCode; CPUTMouseState state = ConvertMouseState(&event.xbutton); state = CPUT_MOUSE_NONE; short xPos = event.xbutton.x; short yPos = event.xbutton.y; handledCode = mCPUT->CPUTHandleMouseEvent(xPos, yPos, 0, state); } break; case MotionNotify: if (mCPUT) { CPUTMouseState state = CPUT_MOUSE_NONE; CPUTEventHandledCode handledCode; // CPUTMouseState state = ConvertMouseState(&event.xbutton); if (event.xbutton.state & Button1Mask) { state = (CPUTMouseState) (state | static_cast<int>(CPUT_MOUSE_LEFT_DOWN)); } if (event.xbutton.state & Button2Mask) { state = (CPUTMouseState) (state | static_cast<int>(CPUT_MOUSE_RIGHT_DOWN)); } short xPos = event.xbutton.x; short yPos = event.xbutton.y; handledCode = mCPUT->CPUTHandleMouseEvent(xPos, yPos, 0, state); } break; default: break; } } else { mCPUT->InnerExecutionLoop(); } } // XDestroyWindow and XCloseDisplay as the next two commands immediately following your event loop, with an exit(0) af /* // // Message pump // MSG msg = { 0 }; bool fRunning = true; while(fRunning) { // PeekMessage() is a passthru on no events // so it allows us to render while no events are present if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) { if (msg.message == WM_QUIT) { PostQuitMessage(0); fRunning = false; } TranslateMessage( &msg ); DispatchMessage( &msg ); } else { // trigger render and other calls mCPUT->InnerExecutionLoop(); } } // // Drain out the rest of the message queue. // while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } if (UnregisterClass(mAppTitle.c_str(), mhInst) == 0) { HandleWin32Error(); } // // Set the window handle to NULL to indicate window shutdown is complete // mhWnd = NULL; // return code mAppClosedReturnCode = (int) msg.wParam; return mAppClosedReturnCode; * */ return 0; }