Example #1
0
File: kbd.c Project: PyroOS/Pyro
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 );
}
Example #2
0
File: ps2.c Project: PyroOS/Pyro
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 );
}
Example #3
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

}
Example #5
0
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;
}
Example #7
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;
}