示例#1
0
void GPC_Engine::UpdateLoadingAnimation(void)
{
	//int delta;

	float progress = DetermineProgress();

	if(progress > m_previousProgress)
	{
//		delta = progress - m_previousProgress;
		m_previousProgress = progress;
		if(m_previousProgress > 1.0)
			m_previousProgress = 1.0;  // limit to 1.0 (has to change !)
//			m_engine->m_previousProgress = 0.0;
	}

	STR_String to = "";
	STR_String from = "";
	STR_String subject = "progress";
	STR_String body;
	body.Format("%f", progress);  // a number between 0.0 and 1.0

	if(m_networkdev)
	{
		// Store a progress message in the network device.
		NG_NetworkMessage* msg = new NG_NetworkMessage(to, from, subject, body);
		m_networkdev->SendNetworkMessage(msg);
		msg->Release();
	}
}
示例#2
0
vector<NG_NetworkMessage*> NG_NetworkScene::FindMessages(
	const STR_String& to,
	const STR_String& from,
	const STR_String& subject,
	bool spamallowed)
{
	vector<NG_NetworkMessage*> foundmessages;
	bool notfound = false;

	// broad phase
	notfound = ((to.IsEmpty() || spamallowed) ? notfound : m_messagesByDestinationName[to] == NULL);
	if (!notfound)
		notfound = (from.IsEmpty() ? notfound : m_messagesBySenderName[from] == NULL);
	if (!notfound)
		notfound = (subject.IsEmpty() ? notfound : m_messagesBySubject[subject] == NULL);
	if (notfound) {
		// it's definitely NOT in the scene, so stop looking
	} else { // narrow phase
		// possibly it's there, but maybe not (false hit)
		if (to.IsEmpty()) {
			// take all messages, and check other fields
			MT_assert(!"objectnames that are empty are not valid, so make it a hobby project :)\n");
		} else {
			//todo: find intersection of messages (that are in other 2 maps)
			vector<NG_NetworkMessage*>** tolistptr = m_messagesByDestinationName[to];
			if (tolistptr) {
				vector<NG_NetworkMessage*>* tolist = *tolistptr;
				vector<NG_NetworkMessage*>::iterator listit;
				for (listit=tolist->begin();!(listit==tolist->end());listit++) {
					NG_NetworkMessage* message = *listit;
					if (ConstraintsAreValid(from, subject, message)) {
						message->AddRef();
						foundmessages.push_back(message);
					}
				} 
			}
			// TODO find intersection of messages (that are in other 2 maps)
			if (spamallowed) {
				tolistptr = m_messagesByDestinationName[""];
				if (tolistptr) {
					vector<NG_NetworkMessage*>* tolist = *tolistptr;
					vector<NG_NetworkMessage*>::iterator listit;
					for (listit=tolist->begin();!(listit==tolist->end());listit++) {
						NG_NetworkMessage* message = *listit;
						if (ConstraintsAreValid(from, subject, message)) {
							message->AddRef();
							foundmessages.push_back(message);
						}
					} 
				}
			}
		}
	} 
	return foundmessages;
}
示例#3
0
static int GPG_PyNextFrame(void *state0)
{
    GPG_NextFrameState *state = (GPG_NextFrameState *) state0;
    int exitcode;
    STR_String exitstring;
    bool run = GPG_NextFrame(state->system, state->app, exitcode, exitstring, state->gs);
    if (run) return 0;
    else {
        if (exitcode)
            fprintf(stderr, "Exit code %d: %s\n", exitcode, exitstring.ReadPtr());
        return 1;
    }
}
示例#4
0
void CParser::Term(int s)
{
	// generates an error if the next symbol isn't the specified symbol s
	// otherwise, skip the symbol
	if (s == sym) NextSym();
	else {
		STR_String msg;
		msg.Format("Warning: " + Symbol2Str(s) + " expected\ncontinuing without it");

//		AfxMessageBox(msg,MB_ICONERROR);

		trace(msg);
	}
}
示例#5
0
char* GHOST_GetTitle(GHOST_WindowHandle windowhandle)
{
	GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
	STR_String title;

	window->getTitle(title);

	char *ctitle = (char*) malloc(title.Length() + 1);

	if (ctitle == NULL) return NULL;
	strcpy(ctitle, title.Ptr());
		
	return ctitle;
}
示例#6
0
void CParser::TermChar(char c)
{
	// generates an error if the next char isn't the specified char c,
	// otherwise, skip the char
	if (ch == c)
	{
		NextCh();
	}
	else
	{
		STR_String str;
		str.Format("Warning: %c expected\ncontinuing without it", c);
		trace(str);
	}
}
示例#7
0
PyObject* KX_MeshProxy::PyGetTextureName(PyObject* args, PyObject* kwds)
{
    int matid= 1;
	STR_String matname;

	if (PyArg_ParseTuple(args,"i:getTextureName",&matid))
	{
		matname = m_meshobj->GetTextureName(matid);
	}
	else {
		return NULL;
	}

	return PyUnicode_FromString(matname.Ptr());
		
}
示例#8
0
bool NG_NetworkScene::ConstraintsAreValid(
	const STR_String& from,
	const STR_String& subject,
	NG_NetworkMessage* message)
{
	vector<NG_NetworkMessage*>** fromlistptr =  m_messagesBySenderName[from];
	vector<NG_NetworkMessage*>** subjectlistptr =  m_messagesBySubject[subject];

	vector<NG_NetworkMessage*>* fromlist = (fromlistptr ? *fromlistptr : NULL);
	vector<NG_NetworkMessage*>* subjectlist = (subjectlistptr ? *subjectlistptr : NULL);
	
	return (
		( from.IsEmpty()    || (!fromlist ? false    : (!(std::find(fromlist->begin(), fromlist->end(), message)       == fromlist->end())))
		) &&
		( subject.IsEmpty() || (!subjectlist ? false : (!(std::find(subjectlist->begin(), subjectlist->end(), message) == subjectlist->end())))
		));
}
示例#9
0
void SCA_KeyboardSensor::AddToTargetProp(int keyIndex)
{
	if (IsPrintable(keyIndex)) {
		CValue* tprop = GetParent()->GetProperty(m_targetprop);
		
		if (tprop) {
			/* overwrite the old property */
			if (IsDelete(keyIndex)) {
				/* strip one char, if possible */
				STR_String newprop = tprop->GetText();
				int oldlength = newprop.Length();
				if (oldlength >= 1 ) {
					int newlength=oldlength;

					BLI_str_cursor_step_prev_utf8(newprop, newprop.Length(), &newlength);
					newprop.SetLength(newlength);

					CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
					GetParent()->SetProperty(m_targetprop, newstringprop);
					newstringprop->Release();
				}				
			} else {
				/* append */
				char pchar = ToCharacter(keyIndex, IsShifted());
				STR_String newprop = tprop->GetText() + pchar;
				CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);			
				GetParent()->SetProperty(m_targetprop, newstringprop);
				newstringprop->Release();
			}
		} else {
			if (!IsDelete(keyIndex)) {
				/* Make a new property. Deletes can be ignored. */
				char pchar = ToCharacter(keyIndex, IsShifted());
				STR_String newprop = pchar;
				CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);			
				GetParent()->SetProperty(m_targetprop, newstringprop);
				newstringprop->Release();
			}
		}
	}
	
}
static std::vector<STR_String> split_string(STR_String str)
{
	std::vector<STR_String> text = std::vector<STR_String>();

	/* Split the string upon new lines */
	int begin=0, end=0;
	while (end < str.Length())
	{
		if (str.GetAt(end) == '\n')
		{
			text.push_back(str.Mid(begin, end-begin));
			begin = end+1;
		}
		end++;
	}
	//Now grab the last line
	text.push_back(str.Mid(begin, end-begin));

	return text;
}
示例#11
0
   STR_String * MSG_Message :: AssembleMessage( )
   {

      // Assemble with existing message string

         STR_String * messageString = new STR_String( idMessage ) ;

         if ( memcmp( STR_ID_NOT_FOUND , messageString->GetString( ) ,
                      strlen( STR_ID_NOT_FOUND )) != 0  )
         {
            DoAssemble( messageString ) ;

            return messageString ;
         } /* end if */

         delete messageString ;
         messageString = NULL ;

      // Assemble with error message string id

         // Assemble with error message string

            messageString = new STR_String( MSG_ErrorIdNotFound ) ;

            if ( vtItems[ INX_LAST_ITEM ] != NULL )
            {
               delete vtItems[ INX_LAST_ITEM ] ;
            } /* if */
            vtItems[ INX_LAST_ITEM ] = new MSG_ItemInteger( idMessage & STR_ID ) ;

            DoAssemble( messageString ) ;

         // Append items to nonexisting message

         char ASCIINum[ BCD_DIM_MAX_ASCII ] ;

            STR_String Separator(    MSG_Separator    ) ;
            STR_String SeparatorEnd( MSG_SeparatorEnd ) ;

            for( int i = 0 ; i < MSG_DIM_ITEMS - 1 ; i ++ )
            {
               if ( vtItems[ i ] != NULL )
               {
                  messageString->Append( Separator ) ;

                  sprintf( ASCIINum , "%d" , i ) ;
                  messageString->Append( ASCIINum ) ;

                  messageString->Append( SeparatorEnd ) ;

                  STR_String * pItemStr = vtItems[ i ]->ToString() ;
                  messageString->Append( pItemStr ) ;
                  delete pItemStr ;

               } /* if */
            } /* for */

            return messageString ;

   } // End of function: MSG  !Assemble the message string
void SCA_KeyboardSensor::AddToTargetProp(int keyIndex, int unicode)
{
	if (IsPrintable(keyIndex)) {
		CValue* tprop = GetParent()->GetProperty(m_targetprop);

		if (IsDelete(keyIndex)) {
			/* Make a new property. Deletes can be ignored. */
			if (tprop) {
				/* overwrite the old property */
				/* strip one char, if possible */
				STR_String newprop = tprop->GetText();
				int oldlength = newprop.Length();
				if (oldlength >= 1 ) {
					int newlength=oldlength;

					BLI_str_cursor_step_prev_utf8(newprop, newprop.Length(), &newlength);
					newprop.SetLength(newlength);

					CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
					GetParent()->SetProperty(m_targetprop, newstringprop);
					newstringprop->Release();
				}
			}
		}
		else {
			char utf8_buf[7];
			size_t utf8_len;

			utf8_len = BLI_str_utf8_from_unicode(unicode, utf8_buf);
			utf8_buf[utf8_len] = '\0';

			STR_String newprop = tprop ? (tprop->GetText() + utf8_buf) : utf8_buf;

			CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
			GetParent()->SetProperty(m_targetprop, newstringprop);
			newstringprop->Release();
		}
	}
}
示例#13
0
void RAS_2DFilterManager::EnableFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFILTER_MODE mode, int pass, STR_String& text)
{
	if(!isshadersupported)
		return;
	if(pass<0 || pass>=MAX_RENDER_PASS)
		return;
	need_tex_update = true;
	if(mode == RAS_2DFILTER_DISABLED)
	{
		m_enabled[pass] = 0;
		return;
	}

	if(mode == RAS_2DFILTER_ENABLED)
	{
		m_enabled[pass] = 1;
		return;
	}

	if(mode == RAS_2DFILTER_NOFILTER)
	{
		if(m_filters[pass])
			glDeleteObjectARB(m_filters[pass]);
		m_enabled[pass] = 0;
		m_filters[pass] = 0;
		m_gameObjects[pass] = NULL;
		m_properties[pass].clear();
		texflag[pass] = 0;
		return;
	}
	
	if(mode == RAS_2DFILTER_CUSTOMFILTER)
	{
		if(m_filters[pass])
			glDeleteObjectARB(m_filters[pass]);
		m_filters[pass] = CreateShaderProgram(text.Ptr());
		m_gameObjects[pass] = gameObj;
		AnalyseShader(pass, propNames);
		m_enabled[pass] = 1;
		return;
	}

	// We've checked all other cases, which means we must be dealing with a builtin filter
	if(m_filters[pass])
		glDeleteObjectARB(m_filters[pass]);
	m_filters[pass] = CreateShaderProgram(mode);
	m_gameObjects[pass] = NULL;
	AnalyseShader(pass, propNames);
	m_enabled[pass] = 1;
}
示例#14
0
void GPC_RenderTools::RenderText(
	int mode,
	RAS_IPolyMaterial* polymat,
	float v1[3], float v2[3], float v3[3], float v4[3], int glattrib)
{
	STR_String mytext = ((CValue*)m_clientobject)->GetPropertyText("Text");
	
	const unsigned int flag = polymat->GetFlag();
	struct MTFace* tface = 0;
	unsigned int *col = 0;

	if(flag & RAS_BLENDERMAT) {
		KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(polymat);
		tface = bl_mat->GetMTFace();
		col = bl_mat->GetMCol();
	} else {
		KX_PolygonMaterial* blenderpoly = static_cast<KX_PolygonMaterial*>(polymat);
		tface = blenderpoly->GetMTFace();
		col = blenderpoly->GetMCol();
	}
	
	GPU_render_text(tface, mode, mytext, mytext.Length(), col, v1, v2, v3, v4, glattrib);
}
示例#15
0
std::vector<STR_String> STR_String::Explode(char c) const
{
	STR_String lcv = *this;
	std::vector<STR_String> uc;

	while (lcv.Length()) {
		int pos = lcv.Find(c);
		if (pos < 0) {
			uc.push_back(lcv);
			lcv.Clear();
		}
		else {
			uc.push_back(lcv.Left(pos));
			lcv = lcv.Mid(pos + 1);
		}
	}

	//uc. -= STR_String("");

	return uc;
}
示例#16
0
void KX_KetsjiEngine::RenderDebugProperties()
{
	STR_String debugtxt;
	int xcoord = 10;	// mmmm, these constants were taken from blender source
	int ycoord = 14;	// to 'mimic' behaviour

	float tottime = m_logger->GetAverage();
	if (tottime < 1e-6f) {
		tottime = 1e-6f;
	}

	// Set viewport to entire canvas
	RAS_Rect viewport;
	m_canvas->SetViewPort(0, 0, int(m_canvas->GetWidth()), int(m_canvas->GetHeight()));
	
	/* Framerate display */
	if (m_show_framerate) {
		debugtxt.Format("swap : %.3f (%.3f frames per second)", tottime, 1.0/tottime);
		m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, 
									debugtxt.Ptr(),
									xcoord,
									ycoord, 
									m_canvas->GetWidth() /* RdV, TODO ?? */, 
									m_canvas->GetHeight() /* RdV, TODO ?? */);
		ycoord += 14;
	}

	/* Profile and framerate display */
	if (m_show_profile)
	{		
		for (int j = tc_first; j < tc_numCategories; j++)
		{
			debugtxt.Format(m_profileLabels[j]);
			m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, 
										debugtxt.Ptr(),
										xcoord,ycoord,
										m_canvas->GetWidth(), 
										m_canvas->GetHeight());
			double time = m_logger->GetAverage((KX_TimeCategory)j);
			debugtxt.Format("%.3fms (%2.2f %%)", time*1000.f, time/tottime * 100.f);
			m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, 
										debugtxt.Ptr(),
										xcoord + 60 ,ycoord,
										m_canvas->GetWidth(), 
										m_canvas->GetHeight());
			ycoord += 14;
		}
	}

	/* Property display*/
	if (m_show_debug_properties && m_propertiesPresent)
	{
		KX_SceneList::iterator sceneit;
		for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
		{
			KX_Scene* scene = *sceneit;
			/* the 'normal' debug props */
			vector<SCA_DebugProp*>& debugproplist = scene->GetDebugProperties();
			
			for (vector<SCA_DebugProp*>::iterator it = debugproplist.begin();
				 !(it==debugproplist.end());it++)
			{
				CValue* propobj = (*it)->m_obj;
				STR_String objname = propobj->GetName();
				STR_String propname = (*it)->m_name;
				if (propname == "__state__")
				{
					// reserve name for object state
					KX_GameObject* gameobj = static_cast<KX_GameObject*>(propobj);
					unsigned int state = gameobj->GetState();
					debugtxt = objname + "." + propname + " = ";
					bool first = true;
					for (int statenum=1;state;state >>= 1, statenum++)
					{
						if (state & 1)
						{
							if (!first)
							{
								debugtxt += ",";
							}
							debugtxt += STR_String(statenum);
							first = false;
						}
					}
					m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, 
													debugtxt.Ptr(),
													xcoord,
													ycoord,
													m_canvas->GetWidth(),
													m_canvas->GetHeight());
					ycoord += 14;
				}
				else
				{
					CValue* propval = propobj->GetProperty(propname);
					if (propval)
					{
						STR_String text = propval->GetText();
						debugtxt = objname + "." + propname + " = " + text;
						m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, 
													debugtxt.Ptr(),
													xcoord,
													ycoord,
													m_canvas->GetWidth(),
													m_canvas->GetHeight());
						ycoord += 14;
					}
				}
			}
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

}
示例#18
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

}
void BL_ConvertActuators(const char* maggiename,
                         struct Object* blenderobject,
                         KX_GameObject* gameobj,
                         SCA_LogicManager* logicmgr,
                         KX_Scene* scene,
                         KX_KetsjiEngine* ketsjiEngine,
                         int activeLayerBitInfo,
                         bool isInActiveLayer,
                         KX_BlenderSceneConverter* converter
                         )
{
	
	int uniqueint = 0;
	int actcount = 0;
	int executePriority = 0;
	bActuator* bact = (bActuator*) blenderobject->actuators.first;
	while (bact)
	{
		actcount++;
		bact = bact->next;
	}
	gameobj->ReserveActuator(actcount);
	bact = (bActuator*) blenderobject->actuators.first;
	while (bact)
	{
		STR_String uniquename = bact->name;
		STR_String& objectname = gameobj->GetName();
		
		SCA_IActuator* baseact = NULL;
		switch (bact->type)
		{
		case ACT_OBJECT:
			{
				bObjectActuator* obact = (bObjectActuator*) bact->data;
				KX_GameObject* obref = NULL;
				MT_Vector3 forcevec(KX_flt_trunc(obact->forceloc[0]),
				                    KX_flt_trunc(obact->forceloc[1]),
				                    KX_flt_trunc(obact->forceloc[2]));
				MT_Vector3 torquevec(obact->forcerot[0],
				                     obact->forcerot[1],
				                     obact->forcerot[2]);
				MT_Vector3 dlocvec(KX_flt_trunc(obact->dloc[0]),
				                   KX_flt_trunc(obact->dloc[1]),
				                   KX_flt_trunc(obact->dloc[2]));
				MT_Vector3 drotvec(KX_flt_trunc(obact->drot[0]),
				                   obact->drot[1],obact->drot[2]);
				MT_Vector3 linvelvec(KX_flt_trunc(obact->linearvelocity[0]),
				                     KX_flt_trunc(obact->linearvelocity[1]),
				                     KX_flt_trunc(obact->linearvelocity[2]));
				MT_Vector3 angvelvec(KX_flt_trunc(obact->angularvelocity[0]),
				                     KX_flt_trunc(obact->angularvelocity[1]),
				                     KX_flt_trunc(obact->angularvelocity[2]));
				short damping = obact->damping;

				/* Blender uses a bit vector internally for the local-flags. In */
				/* KX, we have four bools. The compiler should be smart enough  */
				/* to do the right thing. We need to explicitly convert here!   */
				
				KX_LocalFlags bitLocalFlag;
				
				bitLocalFlag.Force = bool((obact->flag & ACT_FORCE_LOCAL)!=0);
				bitLocalFlag.Torque = bool((obact->flag & ACT_TORQUE_LOCAL) !=0);//rlocal;
				bitLocalFlag.DLoc = bool((obact->flag & ACT_DLOC_LOCAL)!=0);
				bitLocalFlag.DRot = bool((obact->flag & ACT_DROT_LOCAL)!=0);
				bitLocalFlag.LinearVelocity = bool((obact->flag & ACT_LIN_VEL_LOCAL)!=0);
				bitLocalFlag.AngularVelocity = bool((obact->flag & ACT_ANG_VEL_LOCAL)!=0);
				bitLocalFlag.ServoControl = bool(obact->type == ACT_OBJECT_SERVO);
				bitLocalFlag.CharacterMotion = bool(obact->type == ACT_OBJECT_CHARACTER);
				bitLocalFlag.CharacterJump = bool((obact->flag & ACT_CHAR_JUMP)!=0);
				bitLocalFlag.AddOrSetLinV = bool((obact->flag & ACT_ADD_LIN_VEL)!=0);
				bitLocalFlag.AddOrSetCharLoc = bool((obact->flag & ACT_ADD_CHAR_LOC)!=0);
				if (obact->reference && bitLocalFlag.ServoControl)
				{
					obref = converter->FindGameObject(obact->reference);
				}
				
				KX_ObjectActuator* tmpbaseact = new KX_ObjectActuator(
				            gameobj,
				            obref,
				            forcevec.getValue(),
				            torquevec.getValue(),
				            dlocvec.getValue(),
				            drotvec.getValue(),
				            linvelvec.getValue(),
				            angvelvec.getValue(),
				            damping,
				            bitLocalFlag);
				baseact = tmpbaseact;
				break;
			}
		case ACT_ACTION:
			{
				bActionActuator* actact = (bActionActuator*) bact->data;
				STR_String propname = actact->name;
				STR_String propframe = actact->frameProp;

				short ipo_flags = 0;

				// Convert flags
				if (actact->flag & ACT_IPOFORCE) ipo_flags |= BL_Action::ACT_IPOFLAG_FORCE;
				if (actact->flag & ACT_IPOLOCAL) ipo_flags |= BL_Action::ACT_IPOFLAG_LOCAL;
				if (actact->flag & ACT_IPOADD) ipo_flags |= BL_Action::ACT_IPOFLAG_ADD;
				if (actact->flag & ACT_IPOCHILD) ipo_flags |= BL_Action::ACT_IPOFLAG_CHILD;
					
				BL_ActionActuator* tmpbaseact = new BL_ActionActuator(
				            gameobj,
				            propname,
				            propframe,
				            actact->sta,
				            actact->end,
				            actact->act,
				            actact->type, // + 1, because Blender starts to count at zero,
				            actact->blend_mode,
				            actact->blendin,
				            actact->priority,
				            actact->layer,
				            actact->layer_weight,
				            ipo_flags,
				            actact->end_reset,
				            actact->stridelength
				            // Ketsji at 1, because zero is reserved for "NoDef"
				            );
				baseact= tmpbaseact;
				break;
			}
		case ACT_SHAPEACTION:
			{
				if (blenderobject->type==OB_MESH) {
					bActionActuator* actact = (bActionActuator*) bact->data;
					STR_String propname = actact->name;
					STR_String propframe = actact->frameProp;
					
					BL_ShapeActionActuator* tmpbaseact = new BL_ShapeActionActuator(
					            gameobj,
					            propname,
					            propframe,
					            actact->sta,
					            actact->end,
					            actact->act,
					            actact->type, // + 1, because Blender starts to count at zero,
					            actact->blendin,
					            actact->priority,
					            actact->stridelength);
					// Ketsji at 1, because zero is reserved for "NoDef"
					baseact= tmpbaseact;
					break;
				}
				else
					printf ("Discarded shape action actuator from non-mesh object [%s]\n", blenderobject->id.name+2);
			}
		case ACT_LAMP:
			{
				break;
			}
		case ACT_CAMERA:
			{
				bCameraActuator *camact = (bCameraActuator *) bact->data;
				if (camact->ob) {
					KX_GameObject *tmpgob = converter->FindGameObject(camact->ob);
					
					/* visifac, fac and axis are not copied from the struct...   */ 
					/* that's some internal state...                             */
					KX_CameraActuator *tmpcamact = new KX_CameraActuator(
					            gameobj,
					            tmpgob,
					            camact->height,
					            camact->min,
					            camact->max,
					            camact->axis,
					            camact->damping);
					baseact = tmpcamact;
				}
				break;
			}
		case ACT_MESSAGE:
			{
				bMessageActuator *msgAct = (bMessageActuator *) bact->data;
				
				/* Get the name of the properties that objects must own that
				 * we're sending to, if present
				 */
				STR_String toPropName = msgAct->toPropName;
				
				/* Get the Message Subject to send.
				 */
				STR_String subject = msgAct->subject;
				
				/* Get the bodyType
				 */
				int bodyType = msgAct->bodyType;

				/* Get the body (text message or property name whose value
				 * we'll be sending, might be empty
				 */
				const STR_String body = msgAct->body;
				
				KX_NetworkMessageActuator *tmpmsgact = new KX_NetworkMessageActuator(
				            gameobj,					// actuator controlling object
				            scene->GetNetworkScene(),	// needed for replication
				            toPropName,
				            subject,
				            bodyType,
				            body);
				baseact = tmpmsgact;
				break;
			}
		case ACT_MATERIAL:
			{
				break;
			}
		case ACT_SOUND:
			{
				bSoundActuator* soundact = (bSoundActuator*) bact->data;
				/* get type, and possibly a start and end frame */
				KX_SoundActuator::KX_SOUNDACT_TYPE
					soundActuatorType = KX_SoundActuator::KX_SOUNDACT_NODEF;
				
				switch (soundact->type) {
				case ACT_SND_PLAY_STOP_SOUND:
					soundActuatorType = KX_SoundActuator::KX_SOUNDACT_PLAYSTOP;
					break;
				case ACT_SND_PLAY_END_SOUND:
					soundActuatorType = KX_SoundActuator::KX_SOUNDACT_PLAYEND;
					break;
				case ACT_SND_LOOP_STOP_SOUND:
					soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPSTOP;
					break;
				case ACT_SND_LOOP_END_SOUND:
					soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPEND;
					break;
				case ACT_SND_LOOP_BIDIRECTIONAL_SOUND:
					soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL;
					break;
				case ACT_SND_LOOP_BIDIRECTIONAL_STOP_SOUND:
					soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP;
					break;
					
				default:
					/* This is an error!!! */
					soundActuatorType = KX_SoundActuator::KX_SOUNDACT_NODEF;
				}
				
				if (soundActuatorType != KX_SoundActuator::KX_SOUNDACT_NODEF) 
				{
					bSound* sound = soundact->sound;
					bool is3d = soundact->flag & ACT_SND_3D_SOUND ? true : false;
					AUD_Sound* snd_sound = NULL;
					KX_3DSoundSettings settings;
					settings.cone_inner_angle = RAD2DEGF(soundact->sound3D.cone_inner_angle);
					settings.cone_outer_angle = RAD2DEGF(soundact->sound3D.cone_outer_angle);
					settings.cone_outer_gain = soundact->sound3D.cone_outer_gain;
					settings.max_distance = soundact->sound3D.max_distance;
					settings.max_gain = soundact->sound3D.max_gain;
					settings.min_gain = soundact->sound3D.min_gain;
					settings.reference_distance = soundact->sound3D.reference_distance;
					settings.rolloff_factor = soundact->sound3D.rolloff_factor;

					if (!sound)
					{
						std::cout <<	"WARNING: Sound actuator \"" << bact->name <<
										"\" from object \"" <<  blenderobject->id.name+2 <<
										"\" has no sound datablock." << std::endl;
					}
					else
					{
						snd_sound = sound->playback_handle;

						// if sound shall be 3D but isn't mono, we have to make it mono!
						if (is3d)
						{
							snd_sound = AUD_Sound_rechannel(snd_sound, AUD_CHANNELS_MONO);
						}
					}
					KX_SoundActuator* tmpsoundact =
						new KX_SoundActuator(gameobj,
						snd_sound,
						soundact->volume,
						(float)(expf((soundact->pitch / 12.0f) * (float)M_LN2)),
						is3d,
						settings,
						soundActuatorType);

					// if we made it mono, we have to free it
					if(sound && snd_sound && snd_sound != sound->playback_handle)
						AUD_Sound_free(snd_sound);

					tmpsoundact->SetName(bact->name);
					baseact = tmpsoundact;
				}
				break;
			}
		case ACT_PROPERTY:
			{
				bPropertyActuator* propact = (bPropertyActuator*) bact->data;
				SCA_IObject* destinationObj = NULL;
				
				/*
				 * here the destinationobject is searched. problem with multiple scenes: other scenes
				 * have not been converted yet, so the destobj will not be found, so the prop will
				 * not be copied.
				 * possible solutions:
				 * - convert everything when possible and not realtime only when needed.
				 * - let the object-with-property report itself to the act when converted
				 */
				if (propact->ob)
					destinationObj = converter->FindGameObject(propact->ob);
				
				SCA_PropertyActuator* tmppropact = new SCA_PropertyActuator(
				            gameobj,
				            destinationObj,
				            propact->name,
				            propact->value,
				            propact->type + 1); // + 1 because Ketsji Logic starts
				// with 0 for KX_ACT_PROP_NODEF
				baseact = tmppropact;
				break;
			}
		case ACT_EDIT_OBJECT:
			{
				bEditObjectActuator *editobact 
					= (bEditObjectActuator *) bact->data;
				/* There are four different kinds of 'edit object' thingies  */
				/* The alternative to this lengthy conversion is packing     */
				/* several actuators in one, which is not very nice design.. */
				switch (editobact->type) {
				case ACT_EDOB_ADD_OBJECT: 
					{
						
						// does the 'original' for replication exists, and 
						// is it in a non-active layer ?
						SCA_IObject* originalval = NULL;
						if (editobact->ob)
						{
							if (editobact->ob->lay & activeLayerBitInfo)
							{
								fprintf(stderr, "Warning, object \"%s\" from AddObject actuator \"%s\" is not in a hidden layer.\n", objectname.Ptr(), uniquename.Ptr());
							}
							else {
								originalval = converter->FindGameObject(editobact->ob);
							}
						}
						
						KX_SCA_AddObjectActuator* tmpaddact = new KX_SCA_AddObjectActuator(
						            gameobj,
						            originalval,
						            editobact->time,
						            scene,
						            editobact->linVelocity,
						            (editobact->localflag & ACT_EDOB_LOCAL_LINV) != 0,
						            editobact->angVelocity,
						            (editobact->localflag & ACT_EDOB_LOCAL_ANGV) != 0);

								//editobact->ob to gameobj
								baseact = tmpaddact;
					}
					break;
				case ACT_EDOB_END_OBJECT:
					{
						KX_SCA_EndObjectActuator* tmpendact 
							= new KX_SCA_EndObjectActuator(gameobj,scene);
						baseact = tmpendact;
					}
					break;
				case ACT_EDOB_REPLACE_MESH:
					{
						RAS_MeshObject *tmpmesh = converter->FindGameMesh(editobact->me);

						if (!tmpmesh) {
							std::cout << "Warning: object \"" << objectname <<
							"\" from ReplaceMesh actuator \"" << uniquename <<
							"\" uses a mesh not owned by an object in scene \"" <<
							scene->GetName() << "\"." << std::endl;
						}

						KX_SCA_ReplaceMeshActuator* tmpreplaceact = new KX_SCA_ReplaceMeshActuator(
						            gameobj,
						            tmpmesh,
						            scene,
						            (editobact->flag & ACT_EDOB_REPLACE_MESH_NOGFX) == 0,
						            (editobact->flag & ACT_EDOB_REPLACE_MESH_PHYS) != 0);

						baseact = tmpreplaceact;
					}
					break;
				case ACT_EDOB_TRACK_TO:
					{
						SCA_IObject* originalval = NULL;
						if (editobact->ob)
							originalval = converter->FindGameObject(editobact->ob);
							
						KX_TrackToActuator* tmptrackact = new KX_TrackToActuator(
						            gameobj,
						            originalval,
						            editobact->time,
						            editobact->flag,
						            editobact->trackflag,
						            editobact->upflag);
						baseact = tmptrackact;
						break;
					}
				case ACT_EDOB_DYNAMICS:
					{
						KX_SCA_DynamicActuator* tmpdynact = new KX_SCA_DynamicActuator(
						            gameobj,
						            editobact->dyn_operation,
						            editobact->mass);
						baseact = tmpdynact;
					}
				}
				break;
			}
		case ACT_CONSTRAINT:
			{
				float min = 0.0, max = 0.0;
				char *prop = NULL;
				KX_ConstraintActuator::KX_CONSTRAINTTYPE locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_NODEF;
				bConstraintActuator *conact 
					= (bConstraintActuator*) bact->data;
				/* convert settings... degrees in the ui become radians  */ 
				/* internally                                            */ 
				if (conact->type == ACT_CONST_TYPE_ORI) {
					min = conact->minloc[0];
					max = conact->maxloc[0];
					switch (conact->mode) {
					case ACT_CONST_DIRPX:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIX;
						break;
					case ACT_CONST_DIRPY:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIY;
						break;
					case ACT_CONST_DIRPZ:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIZ;
						break;
					}
				} else if (conact->type == ACT_CONST_TYPE_DIST) {
					switch (conact->mode) {
					case ACT_CONST_DIRPX:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPX;
						min = conact->minloc[0];
						max = conact->maxloc[0];
						break;
					case ACT_CONST_DIRPY:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPY;
						min = conact->minloc[1];
						max = conact->maxloc[1];
						break;
					case ACT_CONST_DIRPZ:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPZ;
						min = conact->minloc[2];
						max = conact->maxloc[2];
						break;
					case ACT_CONST_DIRNX:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNX;
						min = conact->minloc[0];
						max = conact->maxloc[0];
						break;
					case ACT_CONST_DIRNY:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNY;
						min = conact->minloc[1];
						max = conact->maxloc[1];
						break;
					case ACT_CONST_DIRNZ:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNZ;
						min = conact->minloc[2];
						max = conact->maxloc[2];
						break;
					}
					prop = conact->matprop;
				} else if (conact->type == ACT_CONST_TYPE_FH) {
					switch (conact->mode) {
					case ACT_CONST_DIRPX:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPX;
						min = conact->minloc[0];
						max = conact->maxloc[0];
						break;
					case ACT_CONST_DIRPY:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPY;
						min = conact->minloc[1];
						max = conact->maxloc[1];
						break;
					case ACT_CONST_DIRPZ:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPZ;
						min = conact->minloc[2];
						max = conact->maxloc[2];
						break;
					case ACT_CONST_DIRNX:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNX;
						min = conact->minloc[0];
						max = conact->maxloc[0];
						break;
					case ACT_CONST_DIRNY:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNY;
						min = conact->minloc[1];
						max = conact->maxloc[1];
						break;
					case ACT_CONST_DIRNZ:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNZ;
						min = conact->minloc[2];
						max = conact->maxloc[2];
						break;
					}
					prop = conact->matprop;
				} else {
					switch (conact->flag) {
					case ACT_CONST_LOCX:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCX; 
						min = conact->minloc[0];
						max = conact->maxloc[0];
						break;
					case ACT_CONST_LOCY:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCY; 
						min = conact->minloc[1];
						max = conact->maxloc[1];
						break;
					case ACT_CONST_LOCZ:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCZ;
						min = conact->minloc[2];
						max = conact->maxloc[2];
						break;
					case ACT_CONST_ROTX:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTX;
						min = conact->minrot[0] * (float)MT_RADS_PER_DEG;
						max = conact->maxrot[0] * (float)MT_RADS_PER_DEG;
						break;
					case ACT_CONST_ROTY:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTY;
						min = conact->minrot[1] * (float)MT_RADS_PER_DEG;
						max = conact->maxrot[1] * (float)MT_RADS_PER_DEG;
						break;
					case ACT_CONST_ROTZ:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTZ;
						min = conact->minrot[2] * (float)MT_RADS_PER_DEG;
						max = conact->maxrot[2] * (float)MT_RADS_PER_DEG;
						break;
					default:
						; /* error */ 
					}
				}
				KX_ConstraintActuator *tmpconact = new KX_ConstraintActuator(
				            gameobj,
				            conact->damp,
				            conact->rotdamp,
				            min,
				            max,
				            conact->maxrot,
				            locrot,
				            conact->time,
				            conact->flag,
				            prop);
				baseact = tmpconact;
				break;
			}
		case ACT_GROUP:
			{
				// deprecated
			}
			break;
		case ACT_SCENE:
			{
				bSceneActuator *sceneact = (bSceneActuator *) bact->data;
				STR_String nextSceneName("");
				
				KX_SceneActuator* tmpsceneact;
				int mode = KX_SceneActuator::KX_SCENE_NODEF;
				KX_Camera *cam = NULL;
				//KX_Scene* scene = NULL;
				switch (sceneact->type)
				{
				case ACT_SCENE_RESUME:
				case ACT_SCENE_SUSPEND:
				case ACT_SCENE_ADD_FRONT:
				case ACT_SCENE_ADD_BACK:
				case ACT_SCENE_REMOVE:
				case ACT_SCENE_SET:
					{
						switch (sceneact->type)
						{
						case ACT_SCENE_RESUME:
							mode = KX_SceneActuator::KX_SCENE_RESUME;
							break;
						case ACT_SCENE_SUSPEND:
							mode = KX_SceneActuator::KX_SCENE_SUSPEND;
							break;
						case ACT_SCENE_ADD_FRONT:
							mode = KX_SceneActuator::KX_SCENE_ADD_FRONT_SCENE;
							break;
						case ACT_SCENE_ADD_BACK:
							mode = KX_SceneActuator::KX_SCENE_ADD_BACK_SCENE;
							break;
						case ACT_SCENE_REMOVE:
							mode = KX_SceneActuator::KX_SCENE_REMOVE_SCENE;
							break;
						case ACT_SCENE_SET:
						default:
							mode = KX_SceneActuator::KX_SCENE_SET_SCENE;
							break;
						};
						
						if (sceneact->scene) {
							nextSceneName = sceneact->scene->id.name + 2;
						}
						
						break;
					}
				case ACT_SCENE_CAMERA:
					mode = KX_SceneActuator::KX_SCENE_SET_CAMERA;
					if (sceneact->camera)
					{
						KX_GameObject *tmp = converter->FindGameObject(sceneact->camera);
						if (tmp && tmp->GetGameObjectType() == SCA_IObject::OBJ_CAMERA)
							cam = (KX_Camera*)tmp;
					}
					break;
				case ACT_SCENE_RESTART:
					{
						
						mode =  KX_SceneActuator::KX_SCENE_RESTART;
						break;
					}
				default:
					; /* flag error */
				}
				tmpsceneact = new KX_SceneActuator(
				            gameobj,
				            mode,
				            scene,
				            ketsjiEngine,
				            nextSceneName,
				            cam);
				baseact = tmpsceneact;
				break;
			}
		case ACT_GAME:
			{
				bGameActuator *gameact = (bGameActuator *) bact->data;
				KX_GameActuator* tmpgameact;
				STR_String filename = maggiename;
				STR_String loadinganimationname = "";
				int mode = KX_GameActuator::KX_GAME_NODEF;
				switch (gameact->type)
				{
				case ACT_GAME_LOAD:
					{
						mode = KX_GameActuator::KX_GAME_LOAD;
						filename = gameact->filename;
						loadinganimationname = gameact->loadaniname;
						break;
					}
				case ACT_GAME_START:
					{
						mode = KX_GameActuator::KX_GAME_START;
						filename = gameact->filename;
						loadinganimationname = gameact->loadaniname;
						break;
					}
				case ACT_GAME_RESTART:
					{
						mode = KX_GameActuator::KX_GAME_RESTART;
						break;
					}
				case ACT_GAME_QUIT:
					{
						mode = KX_GameActuator::KX_GAME_QUIT;
						break;
					}
				case ACT_GAME_SAVECFG:
					{
						mode = KX_GameActuator::KX_GAME_SAVECFG;
						break;
					}
				case ACT_GAME_LOADCFG:
					{
						mode = KX_GameActuator::KX_GAME_LOADCFG;
						break;
					}
					case ACT_GAME_SCREENSHOT:
					{
						mode = KX_GameActuator::KX_GAME_SCREENSHOT;
						filename = gameact->filename;
						break;
					}
				default:
					; /* flag error */
				}
				tmpgameact = new KX_GameActuator(
				            gameobj,
				            mode,
				            filename,
				            loadinganimationname,
				            scene,
				            ketsjiEngine);
				baseact = tmpgameact;

				break;
			}
		case ACT_RANDOM:
			{
				bRandomActuator *randAct 
					= (bRandomActuator *) bact->data;
				
				unsigned long seedArg = randAct->seed;
				if (seedArg == 0)
				{
					seedArg = (int)(ketsjiEngine->GetRealTime()*100000.0);
					seedArg ^= (intptr_t)randAct;
				}
				SCA_RandomActuator::KX_RANDOMACT_MODE modeArg 
					= SCA_RandomActuator::KX_RANDOMACT_NODEF;
				SCA_RandomActuator *tmprandomact;
				float paraArg1 = 0.0;
				float paraArg2 = 0.0;
				
				switch (randAct->distribution) {
				case ACT_RANDOM_BOOL_CONST:
					modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_CONST;
					paraArg1 = (float) randAct->int_arg_1;
					break;
				case ACT_RANDOM_BOOL_UNIFORM:
					modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_UNIFORM;
					break;
				case ACT_RANDOM_BOOL_BERNOUILLI:
					paraArg1 = randAct->float_arg_1;
					modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_BERNOUILLI;
					break;
				case ACT_RANDOM_INT_CONST:
					modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_CONST;
					paraArg1 = (float) randAct->int_arg_1;
					break;
				case ACT_RANDOM_INT_UNIFORM:
					paraArg1 = (float) randAct->int_arg_1;
					paraArg2 = (float) randAct->int_arg_2;
					modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_UNIFORM;
					break;
				case ACT_RANDOM_INT_POISSON:
					paraArg1 = randAct->float_arg_1;
					modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_POISSON;
					break;
				case ACT_RANDOM_FLOAT_CONST:
					paraArg1 = randAct->float_arg_1;
					modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_CONST;
					break;
				case ACT_RANDOM_FLOAT_UNIFORM:
					paraArg1 = randAct->float_arg_1;
					paraArg2 = randAct->float_arg_2;
					modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_UNIFORM;
					break;
				case ACT_RANDOM_FLOAT_NORMAL:
					paraArg1 = randAct->float_arg_1;
					paraArg2 = randAct->float_arg_2;
					modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_NORMAL;
					break;
				case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL:
					paraArg1 = randAct->float_arg_1;
					modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL;
					break;
				default:
					; /* error */
				}
				tmprandomact = new SCA_RandomActuator(
				            gameobj,
				            seedArg,
				            modeArg,
				            paraArg1,
				            paraArg2,
				            randAct->propname);
				baseact = tmprandomact;
			}
			break;

		case ACT_VISIBILITY:
		{
			bVisibilityActuator *vis_act = (bVisibilityActuator *) bact->data;
			KX_VisibilityActuator * tmp_vis_act = NULL;
			bool v = ((vis_act->flag & ACT_VISIBILITY_INVISIBLE) != 0);
			bool o = ((vis_act->flag & ACT_VISIBILITY_OCCLUSION) != 0);
			bool recursive = ((vis_act->flag & ACT_VISIBILITY_RECURSIVE) != 0);

			tmp_vis_act = new KX_VisibilityActuator(gameobj, !v, o, recursive);
			
			baseact = tmp_vis_act;
		}
		break;

		case ACT_STATE:
		{
			bStateActuator *sta_act = (bStateActuator *) bact->data;
			KX_StateActuator * tmp_sta_act = NULL;

			tmp_sta_act = 
				new KX_StateActuator(gameobj, sta_act->type, sta_act->mask);
			
			baseact = tmp_sta_act;
		}
		break;

		case ACT_2DFILTER:
		{
			bTwoDFilterActuator *_2dfilter = (bTwoDFilterActuator*) bact->data;
			SCA_2DFilterActuator *tmp = NULL;

			RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode;
			switch (_2dfilter->type) {
				case ACT_2DFILTER_MOTIONBLUR:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_MOTIONBLUR;
					break;
				case ACT_2DFILTER_BLUR:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_BLUR;
					break;
				case ACT_2DFILTER_SHARPEN:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_SHARPEN;
					break;
				case ACT_2DFILTER_DILATION:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_DILATION;
					break;
				case ACT_2DFILTER_EROSION:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_EROSION;
					break;
				case ACT_2DFILTER_LAPLACIAN:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_LAPLACIAN;
					break;
				case ACT_2DFILTER_SOBEL:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_SOBEL;
					break;
				case ACT_2DFILTER_PREWITT:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_PREWITT;
					break;
				case ACT_2DFILTER_GRAYSCALE:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_GRAYSCALE;
					break;
				case ACT_2DFILTER_SEPIA:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_SEPIA;
					break;
				case ACT_2DFILTER_INVERT:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_INVERT;
					break;
				case ACT_2DFILTER_CUSTOMFILTER:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_CUSTOMFILTER;
					break;
				case ACT_2DFILTER_NOFILTER:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_NOFILTER;
					break;
				case ACT_2DFILTER_DISABLED:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_DISABLED;
					break;
				case ACT_2DFILTER_ENABLED:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_ENABLED;
					break;
				default:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_NOFILTER;
					break;
			}

			tmp = new SCA_2DFilterActuator(gameobj, filtermode,  _2dfilter->flag,
			                               _2dfilter->float_arg, _2dfilter->int_arg,
			                               ketsjiEngine->GetRasterizer(), scene);

			if (_2dfilter->text)
			{
				char *buf;
				// this is some blender specific code
				buf = txt_to_buf(_2dfilter->text);
				if (buf)
				{
					tmp->SetShaderText(buf);
					MEM_freeN(buf);
				}
			}

			baseact = tmp;

		}
		break;
		case ACT_PARENT:
			{
				bParentActuator *parAct = (bParentActuator *) bact->data;
				int mode = KX_ParentActuator::KX_PARENT_NODEF;
				bool addToCompound = true;
				bool ghost = true;
				KX_GameObject *tmpgob = NULL;

				switch (parAct->type) {
					case ACT_PARENT_SET:
						mode = KX_ParentActuator::KX_PARENT_SET;
						tmpgob = converter->FindGameObject(parAct->ob);
						addToCompound = !(parAct->flag & ACT_PARENT_COMPOUND);
						ghost = !(parAct->flag & ACT_PARENT_GHOST);
						break;
					case ACT_PARENT_REMOVE:
						mode = KX_ParentActuator::KX_PARENT_REMOVE;
						tmpgob = NULL;
						break;
				}
	
				KX_ParentActuator *tmpparact
					= new KX_ParentActuator(gameobj,
					mode,
					addToCompound,
					ghost,
					tmpgob);
				baseact = tmpparact;
				break;
			}
		
		case ACT_ARMATURE:
			{
				bArmatureActuator* armAct = (bArmatureActuator*) bact->data;
				KX_GameObject *tmpgob = converter->FindGameObject(armAct->target);
				KX_GameObject *subgob = converter->FindGameObject(armAct->subtarget);
				BL_ArmatureActuator* tmparmact = new BL_ArmatureActuator(
				            gameobj,
				            armAct->type,
				            armAct->posechannel,
				            armAct->constraint,
				            tmpgob,
				            subgob,
				            armAct->weight,
				            armAct->influence);
				baseact = tmparmact;
				break;
			}
		case ACT_STEERING:
			{
				bSteeringActuator *stAct = (bSteeringActuator *) bact->data;
				KX_GameObject *navmeshob = NULL;
				if (stAct->navmesh)
				{
					PointerRNA settings_ptr;
					RNA_pointer_create((ID *)stAct->navmesh, &RNA_GameObjectSettings, stAct->navmesh, &settings_ptr);
					if (RNA_enum_get(&settings_ptr, "physics_type") == OB_BODY_TYPE_NAVMESH)
						navmeshob = converter->FindGameObject(stAct->navmesh);
				}
				KX_GameObject *targetob = converter->FindGameObject(stAct->target);

				int mode = KX_SteeringActuator::KX_STEERING_NODEF;
				switch (stAct->type) {
				case ACT_STEERING_SEEK:
					mode = KX_SteeringActuator::KX_STEERING_SEEK;
					break;
				case ACT_STEERING_FLEE:
					mode = KX_SteeringActuator::KX_STEERING_FLEE;
					break;
				case ACT_STEERING_PATHFOLLOWING:
					mode = KX_SteeringActuator::KX_STEERING_PATHFOLLOWING;
					break;
				}

				bool selfTerminated = (stAct->flag & ACT_STEERING_SELFTERMINATED) !=0;
				bool enableVisualization = (stAct->flag & ACT_STEERING_ENABLEVISUALIZATION) !=0;
				short facingMode = (stAct->flag & ACT_STEERING_AUTOMATICFACING) ? stAct->facingaxis : 0;
				bool normalup = (stAct->flag & ACT_STEERING_NORMALUP) !=0;
				bool lockzvel = (stAct->flag & ACT_STEERING_LOCKZVEL) !=0;
				KX_SteeringActuator *tmpstact
					= new KX_SteeringActuator(gameobj, mode, targetob, navmeshob,stAct->dist, 
					stAct->velocity, stAct->acceleration, stAct->turnspeed, 
					selfTerminated, stAct->updateTime,
					scene->GetObstacleSimulation(), facingMode, normalup, enableVisualization, lockzvel);
				baseact = tmpstact;
				break;
			}
		case ACT_MOUSE:
			{
				bMouseActuator* mouAct = (bMouseActuator*) bact->data;
				int mode = KX_MouseActuator::KX_ACT_MOUSE_NODEF;

				switch (mouAct->type) {
					case ACT_MOUSE_VISIBILITY:
					{
						mode = KX_MouseActuator::KX_ACT_MOUSE_VISIBILITY;
						break;
					}
					case ACT_MOUSE_LOOK:
					{
						mode = KX_MouseActuator::KX_ACT_MOUSE_LOOK;
						break;
					}
				}

				bool visible = (mouAct->flag & ACT_MOUSE_VISIBLE) != 0;
				bool use_axis[2] = {(mouAct->flag & ACT_MOUSE_USE_AXIS_X) != 0, (mouAct->flag & ACT_MOUSE_USE_AXIS_Y) != 0};
				bool reset[2] = {(mouAct->flag & ACT_MOUSE_RESET_X) != 0, (mouAct->flag & ACT_MOUSE_RESET_Y) != 0};
				bool local[2] = {(mouAct->flag & ACT_MOUSE_LOCAL_X) != 0, (mouAct->flag & ACT_MOUSE_LOCAL_Y) != 0};

				SCA_MouseManager* eventmgr = (SCA_MouseManager*) logicmgr->FindEventManager(SCA_EventManager::MOUSE_EVENTMGR);
				if (eventmgr) {
					KX_MouseActuator* tmpbaseact = new KX_MouseActuator(gameobj,
																		ketsjiEngine,
																		eventmgr,
																		mode,
																		visible,
																		use_axis,
																		mouAct->threshold,
																		reset,
																		mouAct->object_axis,
																		local,
																		mouAct->sensitivity,
																		mouAct->limit_x,
																		mouAct->limit_y);
					baseact = tmpbaseact;
				} else {
					//cout << "\n Couldn't find mouse event manager..."; - should throw an error here...
				}
				break;
			}
		default:
			; /* generate some error */
		}
		
		if (baseact && !(bact->flag & ACT_DEACTIVATE))
		{
			baseact->SetExecutePriority(executePriority++);
			uniquename += "#ACT#";
			uniqueint++;
			CIntValue* uniqueval = new CIntValue(uniqueint);
			uniquename += uniqueval->GetText();
			uniqueval->Release();
			baseact->SetName(bact->name);
			baseact->SetLogicManager(logicmgr);
			//gameobj->SetProperty(uniquename,baseact);
			gameobj->AddActuator(baseact);
			
			converter->RegisterGameActuator(baseact, bact);
			// done with baseact, release it
			baseact->Release();
		}
		else if (baseact)
			baseact->Release();
		
		bact = bact->next;
	}
}
void
GHOST_WindowWayland::setTitle(const STR_String& title)
{
	m_title = title.ReadPtr();
	wl_shell_surface_set_title(m_shell_surface, m_title.c_str());
}
示例#21
0
   TST_tpRetCode TST_TestSpecific ::
             PerformSpecificTest( char * Command )
   {

      // Interpret TMSG Reset
      // AE: Reset

         if ( strcmp( Command , Reset_CMD ) == 0 ) 
         {

            for ( int i = 0 ; i < TMSG_dimVtObj ; i++ )
            {
               delete vtObj[ i ] ;
               vtObj[ i ] = NULL ;
            } /* for */

            return TST_RetCodeOK ;

         } // end selection: Interpret TMSG Reset

      // Test: MSG  Message constructor
      // AE: NewMessage  <inxMsg>  <i idString>

         else if ( strcmp( Command , MSG_CMessage_004_CMD ) == 0 )
         {

            /***** Function
            MSG_Message( const long idMessageParm )
            *****/

            int  inxObj   = -1 ;
            int  idString = -1 ;

            int  numRead  = TST_pReader->ReadCommandLine( "ii" ,
                      &inxObj , &idString ) ;

            if ( ( numRead != 2 )
              || !VerifyInxElem( inxObj  , NO ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            MSG_Message * pMsg ;
            switch ( idString )
            {
               case 1 :
                  pMsg = new MSG_Message( TSTMSG_1_0Fields ) ;
                  break ;
               case 2 :
                  pMsg = new MSG_Message( TSTMSG_2_1FieldBeg ) ;
                  break ;
               case 3 :
                  pMsg = new MSG_Message( TSTMSG_3_1FieldMid ) ;
                  break ;
               case 4 :
                  pMsg = new MSG_Message( TSTMSG_4_1FieldEnd ) ;
                  break ;
               case 5 :
                  pMsg = new MSG_Message( TSTMSG_5_2FieldsBeg ) ;
                  break ;
               case 6 :
                  pMsg = new MSG_Message( TSTMSG_6_2FieldsMid ) ;
                  break ;
               case 7 :
                  pMsg = new MSG_Message( TSTMSG_7_2FieldsEnd ) ;
                  break ;
               case 8 :
                  pMsg = new MSG_Message( TSTMSG_8_3Fields ) ;
                  break ;
               case 9 :
                  pMsg = new MSG_Message( TSTMSG_9_1Field ) ;
                  break ;
               default :
                  pMsg = new MSG_Message( idString | STR_MEM ) ;
                  break ;
            } /* switch */

            vtObj[ inxObj ] = pMsg ;

            return TST_RetCodeOK ;

         } // end selection: Test: MSG  Message constructor

      // Test: MSG  Message destructor
      // AE: DestroyMessage  <inxMsg>

         else if ( strcmp( Command , DeleteMSG_CMessage_005_CMD ) == 0 )
         {

            /***** Function
            ~MSG_Message( )
            *****/

            int  inxObj   = -1 ;

            int  numRead  = TST_pReader->ReadCommandLine( "i" , &inxObj ) ;

            if ( ( numRead != 1 )
              || !VerifyInxElem( inxObj  , ANY ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            delete vtObj[ inxObj ] ;
            vtObj[ inxObj ] = NULL ;

            return TST_RetCodeOK ;

         } // end selection: Test: MSG  Message destructor

      // Test: MSG  Add string item
      // AE: AddStringItem  <inxMsg> <i inxItem> <i idMode> <s String>

         else if ( strcmp( Command , AddItem_006_CMD ) == 0 )
         {

            /***** Function
            void AddItem( const int  Index         ,
                          MSG_MessageItem * pItem  )
            *****/

            int  inxObj   = -1 ;
            int  inxItem  = -1 ;
            int  idMode   = -1 ;
            int  sizStr   = -1 ;
            char Str[ TAL_dimBuffer ] ;

            int  numRead  = TST_pReader->ReadCommandLine( "iiis" ,
                      &inxObj , &inxItem , &idMode , &sizStr , Str ) ;

            if ( ( numRead != 4 )
              || !VerifyInxElem( inxObj  , YES ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            if ( Str[ 0 ] == '.' )
            {
               Str[ 0 ] = 0 ;
               sizStr   = 0 ;
            } /* if */

            STR_String StrVal ;
            MSG_ItemString * pItemString = NULL ;

            STR_String * pStr = NULL ;

            switch ( idMode )
            {
               case 1 :                    // char *
                  pItemString = new MSG_ItemString( Str ) ;
                  break ;
               case 2 :                    // STR_String *
                  pStr = new STR_String( Str ) ;
                  pItemString = new MSG_ItemString( pStr ) ;
                  delete pStr ;
                  pStr = NULL ;
                  break ;
               case 3 :
                  StrVal = Str ;           // STR_String value
                  pItemString = new MSG_ItemString( StrVal ) ;
                  break ;
               case 4 :                    // len , char *
                  pItemString = new MSG_ItemString( sizStr , Str ) ;
                  break ;

               default :
                  return TST_RetCodeParmError ;
            } /* switch */

            vtObj[ inxObj ]->AddItem( inxItem , pItemString ) ;

            return TST_RetCodeOK ;

         } // end selection: Test: MSG  Add string item

      // Test: MSG  Add id string item
      // AE: AddIdStringItem  <inxMsg> <i inxItem> <i idString>

         else if ( strcmp( Command , AddIdItem_106_CMD ) == 0 )
         {

            /***** Function
            void AddItem( const int  Index         ,
                          MSG_MessageItem * pItem  )
            *****/

            int  inxObj   = -1 ;
            int  inxItem  = -1 ;
            int  idStr    = -1 ;

            int  numRead  = TST_pReader->ReadCommandLine( "iii" ,
                      &inxObj , &inxItem , &idStr ) ;

            if ( ( numRead != 3 )
              || !VerifyInxElem( inxObj  , YES ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            vtObj[ inxObj ]->AddItem( inxItem , new MSG_ItemString( idStr )) ;

            return TST_RetCodeOK ;

         } // end selection: Test: MSG  Add id string item

      // Test: MSG  Add integer item
      // AE: AddIntegerItem  <inxMsg> <i inxItem> <i Value>

         else if ( strcmp( Command , AddIntegerItem_CMD ) == 0 )
         {

            /***** Function
            void AddItem( const int  Index         ,
                          MSG_MessageItem * pItem  )
            *****/

            int  inxObj   = -1 ;
            int  inxItem  = -1 ;
            int  Value    = -1 ;

            int  numRead  = TST_pReader->ReadCommandLine( "iii" ,
                      &inxObj , &inxItem , &Value ) ;

            if ( ( numRead != 3 )
              || !VerifyInxElem( inxObj  , YES ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            vtObj[ inxObj ]->AddItem( inxItem , new MSG_ItemInteger( Value )) ;

            return TST_RetCodeOK ;

         } // end selection: Test: MSG  Add integer item

      // Test: MSG  Add BCD item
      // AE: AddBCDItem  <inxMsg> <i inxItem> <i idMode> <s String>

         else if ( strcmp( Command , AddBCDItem_CMD ) == 0 )
         {

            /***** Function
            void AddItem( const int  Index         ,
                          MSG_MessageItem * pItem  )
            *****/

            int  inxObj   = -1 ;
            int  inxItem  = -1 ;
            int  sizBCD   = -1 ;
            char ValueBCD[ TAL_dimBuffer ] ;

            int  numRead  = TST_pReader->ReadCommandLine( "iis" ,
                      &inxObj , &inxItem , &sizBCD , ValueBCD ) ;

            if ( ( numRead != 3 )
              || ( sizBCD >= 12 )
              || !VerifyInxElem( inxObj  , YES ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            vtObj[ inxObj ]->AddItem( inxItem , new MSG_ItemBCD( ValueBCD )) ;

            return TST_RetCodeOK ;

         } // end selection: Test: MSG  Add BCD item

      // Test: MSG  Add time item
      // AE: AddTimeItem  <inxMsg> <i inxItem> <i Mode>
      //         Mode == true  -> current time
      //         Mode == false -> session beginning time

         else if ( strcmp( Command , AddTimeItem_CMD ) == 0 )
         {

            /***** Function
            void AddItem( const int  Index         ,
                          MSG_MessageItem * pItem  )
            *****/

            int  inxObj   = -1 ;
            int  inxItem  = -1 ;
            bool Mode     = false ;

            int  numRead  = TST_pReader->ReadCommandLine( "iib" ,
                      &inxObj , &inxItem , &Mode ) ;

            if ( ( numRead != 3 )
              || !VerifyInxElem( inxObj  , YES ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            if ( Mode )
            {
               vtObj[ inxObj ]->AddItem( inxItem , new  MSG_ItemTime( MSG_TimeCurrent )) ;
            } else
            {
               vtObj[ inxObj ]->AddItem( inxItem , new  MSG_ItemTime( MSG_TimeInitial )) ;
            } /* if */

            return TST_RetCodeOK ;

         } // end selection: Test: MSG  Add time item

      // Test: MSG  Assemble the message string
      // AE: AssembleMessage  <inxMsg> <s expString>

         else if ( strcmp( Command , AssembleMessage_007_CMD ) == 0 )
         {

            /***** Function
            STR_String * AssembleMessage( )
            *****/

            int  inxObj   = -1 ;
            int  expSiz   = -1 ;
            char expStr[ TAL_dimBuffer ] ;

            int  numRead  = TST_pReader->ReadCommandLine( "is" ,
                      &inxObj , &expSiz , expStr ) ;

            if ( ( numRead != 2 )
              || !VerifyInxElem( inxObj  , YES ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            STR_String * isString = vtObj[ inxObj ]->AssembleMessage( ) ;

            TST_tpRetCode retCode = Compare( isString->GetLength( ) ,
                      isString->GetString( ) , expSiz , expStr ,
                      "Incorrect message string." ) ;

            delete isString ;
            return retCode ;

         } // end selection: Test: MSG  Assemble the message string

      // Test: MSG  Get message id
      // AE: GetMessageId  <inxMsg> <i espIdString>

         else if ( strcmp( Command , GetMessageId_008_CMD ) == 0 )
         {

            /***** Function
            long GetMessageId( )
            *****/

            int  inxObj   = -1 ;
            int  inxMsg   = -1 ;
            int  expValue = -1 ;

            int  numRead  = TST_pReader->ReadCommandLine( "ii" ,
                      &inxObj , &inxMsg ) ;

            if ( ( numRead != 2 )
              || !VerifyInxElem( inxObj  , YES ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            switch ( inxMsg )
            {
               case 1 :
                  expValue = TSTMSG_1_0Fields ;
                  break ;
               case 2 :
                  expValue = TSTMSG_2_1FieldBeg ;
                  break ;
               case 3 :
                  expValue = TSTMSG_3_1FieldMid ;
                  break ;
               case 4 :
                  expValue = TSTMSG_4_1FieldEnd ;
                  break ;
               case 5 :
                  expValue = TSTMSG_5_2FieldsBeg ;
                  break ;
               case 6 :
                  expValue = TSTMSG_6_2FieldsMid ;
                  break ;
               case 7 :
                  expValue = TSTMSG_7_2FieldsEnd ;
                  break ;
               case 8 :
                  expValue = TSTMSG_8_3Fields ;
                  break ;
               case 9 :
                  expValue = TSTMSG_9_1Field ;
                  break ;
               default :
                  expValue = 0 ;
                  break ;
            } /* switch */

            return Compare( vtObj[ inxObj ]->GetMessageId( ) , expValue ,
                     "Incorrect message id value." ) ;

         } // end selection: Test: MSG  Get message id

      // Test: MSG  Replace message id
      // AE: ReplaceMessageId  <inxMsg> <i newIdString>

         else if ( strcmp( Command , ReplaceMessageId_009_CMD ) == 0 )
         {

            /***** Function
            void ReplaceMessageId( const long idMessageParm )
            *****/

            int  inxObj   = -1 ;
            int  inxMsg   = -1 ;
            int  newId    = -1 ;

            int  numRead  = TST_pReader->ReadCommandLine( "ii" ,
                      &inxObj , &inxMsg ) ;

            if ( ( numRead != 2 )
              || !VerifyInxElem( inxObj  , YES ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            switch ( inxMsg )
            {
               case 1 :
                  newId = TSTMSG_1_0Fields ;
                  break ;
               case 2 :
                  newId = TSTMSG_2_1FieldBeg ;
                  break ;
               case 3 :
                  newId = TSTMSG_3_1FieldMid ;
                  break ;
               case 4 :
                  newId = TSTMSG_4_1FieldEnd ;
                  break ;
               case 5 :
                  newId = TSTMSG_5_2FieldsBeg ;
                  break ;
               case 6 :
                  newId = TSTMSG_6_2FieldsMid ;
                  break ;
               case 7 :
                  newId = TSTMSG_7_2FieldsEnd ;
                  break ;
               case 8 :
                  newId = TSTMSG_8_3Fields ;
                  break ;
               case 9 :
                  newId = TSTMSG_9_1Field ;
                  break ;
               default :
                  newId = inxMsg | STR_MEM ;
                  break ;
            } /* switch */

            vtObj[ inxObj ]->ReplaceMessageId( newId ) ;

            return TST_RetCodeOK ;

         } // end selection: Test: MSG  Replace message id

      // Test: MSG  !Get message item
      // AE: GetItem  <inxMsg> <i inxItem> <espString>

         else if ( strcmp( Command , GetItem_101_CMD ) == 0 )
         {

            struct PointerEnvelope
            {
               STR_String * pString ;

               PointerEnvelope( )
               {
                  pString = NULL ;
               }

              ~PointerEnvelope( )
               {
                  delete pString ;
               }
            } envelope ; /* struct */

            /***** Function
            MSG_MessageItem * GetItem( int inxItem )
            *****/

            int   inxObj   = -1 ;
            int   inxItem  = -1 ;
            int   expSiz   = -1 ;
            char  expStr[ TAL_dimBuffer ] ;

            int  numRead  = TST_pReader->ReadCommandLine( "iis" ,
                      &inxObj , &inxItem , &expSiz , expStr ) ;

            if ( ( numRead != 3 )
              || !VerifyInxElem( inxObj  , YES ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            MSG_MessageItem * pItem = vtObj[ inxObj ]->GetItem( inxItem ) ;

            if ( pItem != NULL )
            {
               envelope.pString = pItem->ToString( ) ;
               return Compare( envelope.pString->GetLength( ) ,
                      envelope.pString->GetString( ) , expSiz , expStr ,
                      "Incorrect non null item string." ) ;
            } /* if */

            return Compare( 1 , "." , expSiz , expStr ,
                      "Incorrect null item string." ) ;

         } // end selection: Test: MSG  !Get message item

      // Test: MSGI Get item type identifier
      // AE: GetItemTypeId  <inxMsg> <i inxItem> <espIdType>

         else if ( strcmp( Command , GetItemTypeId_100_CMD ) == 0 )
         {

            /***** Function
            MSG_tpItemTypeId GetItemTypeId( )
            *****/

            int  inxObj   = -1 ;
            int  inxItem  = -1 ;
            int  expValue = -1 ;

            int  numRead  = TST_pReader->ReadCommandLine( "iii" ,
                      &inxObj , &inxItem , &expValue ) ;

            if ( ( numRead != 3 )
              || !VerifyInxElem( inxObj  , YES ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            MSG_MessageItem * pItem = vtObj[ inxObj ]->GetItem( inxItem ) ;

            MSG_tpItemTypeId typeId = MSG_ItemTypeIdNull ;

            if ( pItem != NULL )
            {
               typeId = pItem->GetItemTypeId( ) ;
            } /* if */

            return Compare( typeId , expValue , "Incorrect type id value." ) ;

         } // end selection: Test: MSGI Get item type identifier

      return TST_RetCodeUnknown ;

   } // End of function: TMSG !P Perform specific test actions
示例#22
0
   TST_tpRetCode TST_TestSpecific ::
             PerformSpecificTest( char * Command )
   {

      // Interpret TCFG Reset
      // AE: Reset

         if ( strcmp( Command , Reset_CMD ) == 0 ) 
         {

            for ( int i = 0 ; i < TCFG_dimVtObj ; i++ )
            {
               delete vtObj[ i ] ;
               vtObj[ i ] = NULL ;
            } /* for */

            return TST_RetCodeOK ;

         } // end selection: Interpret TCFG Reset

      // Test: CFG  !Construct a configuration list
      // AE: NewParamList  <inxObj>

         else if ( strcmp( Command , CFG_CParameterList_002_CMD ) == 0 )
         {

            /***** Function
            CFG_ConfigurationList( )
            *****/

            int  inxObj   = -1 ;

            int  numRead  = TST_pReader->ReadCommandLine( "i" , &inxObj ) ;

            if ( ( numRead != 1 )
              || !VerifyInxElem( inxObj , NO ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            vtObj[ inxObj ] = new CFG_ConfigurationList( ) ;

            return TST_RetCodeOK ;

         } // end selection: Test: CFG  !Construct a configuration list

      // Test: CFG  !Destroy a parameter list
      // AE: DeleteParamList  <inxObj>

         else if ( strcmp( Command , DeleteCFG_CParameterList_003_CMD ) == 0 )
         {

            /***** Function
            ~CFG_ConfigurationList( )
            *****/

            int  inxObj   = -1 ;

            int  numRead  = TST_pReader->ReadCommandLine( "i" , &inxObj ) ;

            if ( ( numRead != 1 )
              || !VerifyInxElem( inxObj  , ANY ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            delete vtObj[ inxObj ] ;
            vtObj[ inxObj ] = NULL ;

            return TST_RetCodeOK ;

         } // end selection: Test: CFG  !Destroy a parameter list

      // Test: CFG  !Build from given file
      // AE: BuildList   <inxObj> <s EnvName> <s FileName> <s ExtensionName> <b expReturn>
      //                    EnvName  == "."  ==> NULL reads the file identified
      //                                         by the "TALISMAN" environment variable
      //                    FileName == "."  ==> NULL reads the file identified
      //                                         by the environment variable
      //                    ExtName  == "."  ==> NULL uses "config" as deafult extension
      //                                         name

         else if ( strcmp( Command , BuildLineList_006_CMD ) == 0 )
         {

            /***** Function
            bool BuildLineList( char * FileName      ,
                                char * FileExtension  )
            *****/

            int  inxObj   = -1 ;
            bool expRet   = false ;

            int  sizFileName = -1 ;
            char FileName[ TAL_dimBuffer ] ;

            int  sizExtName  = -1 ;
            char ExtName[ TAL_dimBuffer ] ;

            int  numRead  = TST_pReader->ReadCommandLine( "issb" ,
                      &inxObj , &sizFileName , FileName ,
                                &sizExtName  , ExtName  , &expRet ) ;

            if ( ( numRead != 4 )
              || !VerifyInxElem( inxObj  , YES ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            return CompareBool( vtObj[ inxObj ]->BuildLineList(
                                ( strcmp( FileName , "." ) != 0 ? FileName : NULL ) ,
                                ( strcmp( ExtName  , "." ) != 0 ? ExtName  : NULL )) ,
                                expRet , "Incorrect configuration build return." ) ;

         } // end selection: Test: CFG  !Build from given file

      // Test: CFG  !Write configuration file
      // AE: WriteList   <inxObj> <s FileNmae> <s ExtensionName> <b expReturn>
      //                    FileName == "."  ==> NULL
      //                    ExtName  == "."  ==> NULL

         else if ( strcmp( Command , WriteConfigurationList_006_CMD ) == 0 )
         {

            /***** Function
            bool WriteConfigurationList( char * FileName ,
                                         char * ExtensionName = NULL )
            *****/

            int  inxObj   = -1 ;
            bool expRet   = false ;

            int  sizFileName = -1 ;
            char FileName[ TAL_dimBuffer ] ;

            int  sizExtName  = -1 ;
            char ExtName[ TAL_dimBuffer ] ;

            int  numRead  = TST_pReader->ReadCommandLine( "issb" ,
                      &inxObj , &sizFileName , FileName ,
                                &sizExtName  , ExtName  , &expRet ) ;

            if ( ( numRead != 4 )
              || !VerifyInxElem( inxObj  , YES ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            return CompareBool( vtObj[ inxObj ]->WriteConfigurationList(
                                ( strcmp( FileName , "." ) != 0 ? FileName : NULL ) ,
                                ( strcmp( ExtName  , "." ) != 0 ? ExtName  : NULL )) ,
                                expRet , "Incorrect configuration write return." ) ;

         } // end selection: Test: CFG  !Write configuration file

      // Test: CFG  !Get a parameter value
      // AE: GetParameter <inxObj> <s SectionName> <s ParameterName> <s expValue>

         else if ( strcmp( Command , GetParameter_007_CMD ) == 0 )
         {

            /***** Function
            STR_String * GetParameterValue( char * SectionName   ,
                                             char * AttributeName  )
            *****/

            int  inxObj   = -1 ;

            int  sizSecName = -1 ;
            char SecName[ TAL_dimBuffer ] ;

            int  sizParmName  = -1 ;
            char ParmName[ TAL_dimBuffer ] ;

            int  sizexpValue  = -1 ;
            char expValue[ TAL_dimBuffer ] ;

            int  numRead  = TST_pReader->ReadCommandLine( "isss" ,
                      &inxObj , &sizSecName   , SecName  ,
                                &sizParmName  , ParmName , &sizexpValue , expValue ) ;

            if ( ( numRead != 4 )
              || !VerifyInxElem( inxObj  , YES ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            STR_String * pStr = vtObj[ inxObj ]->GetParameterValue( SecName , ParmName ) ;

            if ( pStr == NULL )
            {
               if ( strcmp( expValue , "." ) == 0 )
               {
                  return TST_RetCodeOK ;
               } /* if */
               DisplayErrorMsg( "Expected parameter has not been found." ) ;
               return TST_RetCodeFailure ;
            } /* if */

            TST_tpRetCode retCode = Compare( pStr->GetString( ) , expValue ,
                      sizexpValue , "Incorrect parameter value." ) ;

            delete pStr ;

            return retCode ;

         } // end selection: Test: CFG  !Get a parameter value

      // Test: CFG  !Set a parameter value
      // AE: SetParameter <inxObj> <s SectionName> <s ParameterName> <s newValue> <b expRet>

         else if ( strcmp( Command , SetParameter_013_CMD ) == 0 )
         {

            /***** Function
            bool SetParameterValue( char        * SectionName ,
                                    char        * ParameterName ,
                                    STR_String * ParameterValue )
            *****/

            int  inxObj   = -1 ;
            bool expRet   = false ;

            int  sizSecName = -1 ;
            char SecName[ TAL_dimBuffer ] ;

            int  sizParmName  = -1 ;
            char ParmName[ TAL_dimBuffer ] ;

            int  sizValue  = -1 ;
            char Value[ TAL_dimBuffer ] ;

            int  numRead  = TST_pReader->ReadCommandLine( "isssb" ,
                      &inxObj , &sizSecName   , SecName  ,
                                &sizParmName  , ParmName , &sizValue , Value , &expRet ) ;

            if ( ( numRead != 5 )
              || !VerifyInxElem( inxObj  , YES ))
            {
               return TST_RetCodeParmError ;
            } /* if */

            STR_String * pVal = new STR_String( sizValue , Value ) ;
            bool isRet = vtObj[ inxObj ]->SetParameterValue( SecName , ParmName , pVal ) ;

            return CompareBool( isRet , expRet , "Incorrect set parameter return." );

         } // end selection: Test: CFG  !Set a parameter value

      // Perform compare file
      // AE: CompareFile  <s FileA> <s extFileA> <s FileB> <s extFileB> <b expRet>

         else if ( strcmp( Command , CompareFile_CMD ) == 0 )
         {

            int  lenFileA = -1 ;
            char fileA[ TAL_dimBuffer ] ;
            int  lenExtA  = -1 ;
            char ExtA[  TAL_dimBuffer ] ;
            int  lenFileB = -1 ;
            char fileB[ TAL_dimBuffer ] ;
            int  lenExtB  = -1 ;
            char ExtB[  TAL_dimBuffer ] ;
            bool expBool  = false ;

            int  numRead  = TST_pReader->ReadCommandLine( "ssssb" ,
                      &lenFileA , fileA , &lenExtA , ExtA ,
                      &lenFileB , fileB , &lenExtB , ExtB , &expBool ) ;

            if ( numRead != 5 )
            {
               return TST_RetCodeParmError ;
            } /* if */

            return CompareBool( SIO_CompareFile( fileA , ExtA , fileB , ExtB ) ,
                      expBool , "Incorrect comparison." ) ;

         } // end selection: Perform compare file

      // Test: CFGE !Configuration element constructor
      // AE: CFGE_LineListElem_002_CMD

         else if ( strcmp( Command , CFGE_CLineListElem_002_CMD ) == 0 )
         {

            /***** Function
            CFGE_LineListElem( )
            *****/

            return TST_RetCodeNotImplemented ;

         } // end selection: Test: CFGE !Configuration element constructor

      // Test: CFGE !Configuration element destructor
      // AE: DeleteCFGE_LineListElem_003_CMD

         else if ( strcmp( Command , DeleteCFGE_CLineListElem_003_CMD ) == 0 )
         {

            /***** Function
            ~CFGE_LineListElem( )
            *****/

            return TST_RetCodeNotImplemented ;

         } // end selection: Test: CFGE !Configuration element destructor

      // Test var: Line type
      // AE: LineType_006

         else if ( strcmp( Command , LineType_006 ) == 0 )
         {

            /***** Variable
            tpLineType LineType ;
            *****/

            return TST_RetCodeNotImplemented ;

         } // end selection: Test var: Line type

      // Test var: Next section element
      // AE: proxSection_007

         else if ( strcmp( Command , proxSection_007 ) == 0 )
         {

            /***** Variable
            CFG_ParamenterListElement * proxSection ;
            *****/

            return TST_RetCodeNotImplemented ;

         } // end selection: Test var: Next section element

      // Test var: Next atribute element
      // AE: proxAttribute_008

         else if ( strcmp( Command , proxAttribute_008 ) == 0 )
         {

            /***** Variable
            CFG_ParamenterListElement * proxAttribute ;
            *****/

            return TST_RetCodeNotImplemented ;

         } // end selection: Test var: Next atribute element

      // Test var: Element name
      // AE: pElementName_009

         else if ( strcmp( Command , pElementName_009 ) == 0 )
         {

            /***** Variable
            STR_String * pElementName ;
            *****/

            return TST_RetCodeNotImplemented ;

         } // end selection: Test var: Element name

      // Test var: Element value
      // AE: pElementValue_021

         else if ( strcmp( Command , pElementValue_021 ) == 0 )
         {

            /***** Variable
            STR_String * pElementValue ;
            *****/

            return TST_RetCodeNotImplemented ;

         } // end selection: Test var: Element value

      return TST_RetCodeUnknown ;

   } // End of function: TCFG !P Perform specific test actions
示例#23
0
void
GHOST_WindowSDL::setTitle(const STR_String& title)
{
	SDL_SetWindowTitle(m_sdl_win, title.ReadPtr());
}
示例#24
0
int main(int argc, char** argv)
{
    int i;
    int argc_py_clamped= argc; /* use this so python args can be added after ' - ' */
    bool error = false;
    SYS_SystemHandle syshandle = SYS_GetSystem();
    bool fullScreen = false;
    bool fullScreenParFound = false;
    bool windowParFound = false;
#ifdef WIN32
    bool closeConsole = true;
#endif
    RAS_IRasterizer::StereoMode stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
    bool stereoWindow = false;
    bool stereoParFound = false;
    int stereoFlag = STEREO_NOSTEREO;
    int domeFov = -1;
    int domeTilt = -200;
    int domeMode = 0;
    char* domeWarp = NULL;
    Text *domeText  = NULL;
    int windowLeft = 100;
    int windowTop = 100;
    int windowWidth = 640;
    int windowHeight = 480;
    GHOST_TUns32 fullScreenWidth = 0;
    GHOST_TUns32 fullScreenHeight= 0;
    int fullScreenBpp = 32;
    int fullScreenFrequency = 60;
    GHOST_TEmbedderWindowID parentWindow = 0;
    bool isBlenderPlayer = false; //true when lauching from blender or command line. false for bundled player
    int validArguments=0;
    bool samplesParFound = false;
    GHOST_TUns16 aasamples = 0;

#ifdef __linux__
#ifdef __alpha__
    signal (SIGFPE, SIG_IGN);
#endif /* __alpha__ */
#endif /* __linux__ */

#ifdef WITH_SDL_DYNLOAD
    sdlewInit();
#endif

    BKE_appdir_program_path_init(argv[0]);
    BKE_tempdir_init(NULL);

    // We don't use threads directly in the BGE, but we need to call this so things like
    // freeing up GPU_Textures works correctly.
    BLI_threadapi_init();

    RNA_init();

    init_nodesystem();

    initglobals();

    U.gameflags |= USER_DISABLE_VBO;
    // We load our own G.main, so free the one that initglobals() gives us
    BKE_main_free(G.main);
    G.main = NULL;

    MEM_CacheLimiter_set_disabled(true);
    IMB_init();
    BKE_images_init();
    BKE_modifier_init();
    DAG_init();

#ifdef WITH_FFMPEG
    IMB_ffmpeg_init();
#endif

    // Setup builtin font for BLF (mostly copied from creator.c, wm_init_exit.c and interface_style.c)
    BLF_init(11, U.dpi);
    BLF_lang_init();
    BLF_lang_set("");

    BLF_load_mem("default", (unsigned char*)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
    if (blf_mono_font == -1)
        blf_mono_font = BLF_load_mem_unique("monospace", (unsigned char*)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size);

    // Parse command line options
#if defined(DEBUG)
    printf("argv[0] = '%s'\n", argv[0]);
#endif

#ifdef WIN32
    if (scr_saver_init(argc, argv))
    {
        switch (scr_saver_mode)
        {
        case SCREEN_SAVER_MODE_CONFIGURATION:
            MessageBox(scr_saver_hwnd, "This screen saver has no options that you can set", "Screen Saver", MB_OK);
            break;
        case SCREEN_SAVER_MODE_PASSWORD:
        /* This is W95 only, which we currently do not support.
         * Fall-back to normal screen saver behavior in that case... */
        case SCREEN_SAVER_MODE_SAVER:
            fullScreen = true;
            fullScreenParFound = true;
            break;

        case SCREEN_SAVER_MODE_PREVIEW:
            /* This will actually be handled somewhere below... */
            break;
        }
    }
#endif
    // XXX add the ability to change this values to the command line parsing.
    U.mixbufsize = 2048;
    U.audiodevice = 2;
    U.audiorate = 44100;
    U.audioformat = 0x24;
    U.audiochannels = 2;

    // XXX this one too
    U.anisotropic_filter = 2;
    // enable fast mipmap generation
    U.use_gpu_mipmap = 1;

    sound_init_once();

    set_free_windowmanager_cb(wm_free);

    /* if running blenderplayer the last argument can't be parsed since it has to be the filename. else it is bundled */
    isBlenderPlayer = !BLO_is_a_runtime(argv[0]);
    if (isBlenderPlayer)
        validArguments = argc - 1;
    else
        validArguments = argc;


    /* Parsing command line arguments (can be set from WM_OT_blenderplayer_start) */
#if defined(DEBUG)
    printf("Parsing command line arguments...\n");
    printf("Num of arguments is: %i\n", validArguments-1); //-1 because i starts at 1
#endif

    for (i = 1; (i < validArguments) && !error
#ifdef WIN32
            && scr_saver_mode == SCREEN_SAVER_MODE_NONE
#endif
            ;)

    {
#if defined(DEBUG)
        printf("argv[%d] = '%s'\n", i, argv[i]);
#endif
        if (argv[i][0] == '-')
        {
            /* ignore all args after " - ", allow python to have own args */
            if (argv[i][1]=='\0') {
                argc_py_clamped= i;
                break;
            }

            switch (argv[i][1])
            {
            case 'g': //game engine options (show_framerate, fixedtime, etc)
            {
                i++;
                if (i <= validArguments)
                {
                    char* paramname = argv[i];
                    // Check for single value versus assignment
                    if (i+1 <= validArguments && (*(argv[i+1]) == '='))
                    {
                        i++;
                        if (i + 1 <= validArguments)
                        {
                            i++;
                            // Assignment
                            SYS_WriteCommandLineInt(syshandle, paramname, atoi(argv[i]));
                            SYS_WriteCommandLineFloat(syshandle, paramname, atof(argv[i]));
                            SYS_WriteCommandLineString(syshandle, paramname, argv[i]);
#if defined(DEBUG)
                            printf("%s = '%s'\n", paramname, argv[i]);
#endif
                            i++;
                        }
                        else
                        {
                            error = true;
                            printf("error: argument assignment %s without value.\n", paramname);
                        }
                    }
                    else
                    {
//						SYS_WriteCommandLineInt(syshandle, argv[i++], 1);
                    }
                }
                break;
            }
            case 'd': //debug on
            {
                i++;
                G.debug |= G_DEBUG;
                MEM_set_memory_debug();
#ifdef DEBUG
                BLI_mempool_set_memory_debug();
#endif
                break;
            }
            case 'f': //fullscreen mode
            {
                i++;
                fullScreen = true;
                fullScreenParFound = true;
                if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
                {
                    fullScreenWidth = atoi(argv[i++]);
                    fullScreenHeight = atoi(argv[i++]);
                    if ((i + 1) <= validArguments && argv[i][0] != '-')
                    {
                        fullScreenBpp = atoi(argv[i++]);
                        if ((i + 1) <= validArguments && argv[i][0] != '-')
                            fullScreenFrequency = atoi(argv[i++]);
                    }
                }
                else if ((i + 1) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
                {
                    error = true;
                    printf("error: to define fullscreen width or height, both options must be used.\n");
                }
                break;
            }
            case 'w': //display in a window
            {
                i++;
                fullScreen = false;
                windowParFound = true;

                // Parse window position and size options
                if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
                {
                    windowWidth = atoi(argv[i++]);
                    windowHeight = atoi(argv[i++]);

                    if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
                    {
                        windowLeft = atoi(argv[i++]);
                        windowTop = atoi(argv[i++]);
                    }
                    else if ((i + 1) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
                    {
                        error = true;
                        printf("error: to define the window left or right coordinates, both options must be used.\n");
                    }
                }
                else if ((i + 1) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
                {
                    error = true;
                    printf("error: to define the window's width or height, both options must be used.\n");
                }
                break;
            }
            case 'h': //display help
            {
                usage(argv[0], isBlenderPlayer);
                return 0;
                break;
            }
            case 'i': //parent window ID
            {
                i++;
                if ( (i + 1) <= validArguments )
                    parentWindow = atoi(argv[i++]);
                else {
                    error = true;
                    printf("error: too few options for parent window argument.\n");
                }
#if defined(DEBUG)
                printf("XWindows ID = %d\n", parentWindow);
#endif // defined(DEBUG)
                break;
            }
            case 'm': //maximum anti-aliasing (eg. 2,4,8,16)
            {
                i++;
                samplesParFound = true;
                if ((i+1) <= validArguments )
                    aasamples = atoi(argv[i++]);
                else
                {
                    error = true;
                    printf("error: No argument supplied for -m");
                }
                break;
            }
            case 'c': //keep console (windows only)
            {
                i++;
#ifdef WIN32
                closeConsole = false;
#endif
                break;
            }
            case 's': //stereo mode
            {
                i++;
                if ((i + 1) <= validArguments)
                {
                    stereoParFound = true;
                    stereoFlag = STEREO_ENABLED;

                    if (!strcmp(argv[i], "nostereo"))  // may not be redundant if the file has different setting
                    {
                        stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
                        stereoFlag = STEREO_NOSTEREO;
                    }

                    // only the hardware pageflip method needs a stereo window
                    else if (!strcmp(argv[i], "hwpageflip")) {
                        stereomode = RAS_IRasterizer::RAS_STEREO_QUADBUFFERED;
                        stereoWindow = true;
                    }
                    else if (!strcmp(argv[i], "syncdoubling"))
                        stereomode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW;

                    else if (!strcmp(argv[i], "3dtvtopbottom"))
                        stereomode = RAS_IRasterizer::RAS_STEREO_3DTVTOPBOTTOM;

                    else if (!strcmp(argv[i], "anaglyph"))
                        stereomode = RAS_IRasterizer::RAS_STEREO_ANAGLYPH;

                    else if (!strcmp(argv[i], "sidebyside"))
                        stereomode = RAS_IRasterizer::RAS_STEREO_SIDEBYSIDE;

                    else if (!strcmp(argv[i], "interlace"))
                        stereomode = RAS_IRasterizer::RAS_STEREO_INTERLACED;

                    else if (!strcmp(argv[i], "vinterlace"))
                        stereomode = RAS_IRasterizer::RAS_STEREO_VINTERLACE;

#if 0
//					// future stuff
//					else if (!strcmp(argv[i], "stencil")
//						stereomode = RAS_STEREO_STENCIL;
#endif
                    else
                    {
                        error = true;
                        printf("error: stereomode '%s' unrecognized.\n", argv[i]);
                    }

                    i++;
                }
                else
                {
                    error = true;
                    printf("error: too few options for stereo argument.\n");
                }
                break;
            }
            case 'D': //dome mode
            {
                stereoFlag = STEREO_DOME;
                stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
                i++;
                if ((i + 1) <= validArguments)
                {
                    if (!strcmp(argv[i], "angle")) {
                        i++;
                        domeFov = atoi(argv[i++]);
                    }
                    if (!strcmp(argv[i], "tilt")) {
                        i++;
                        domeTilt = atoi(argv[i++]);
                    }
                    if (!strcmp(argv[i], "warpdata")) {
                        i++;
                        domeWarp = argv[i++];
                    }
                    if (!strcmp(argv[i], "mode")) {
                        i++;
                        if (!strcmp(argv[i], "fisheye"))
                            domeMode = DOME_FISHEYE;

                        else if (!strcmp(argv[i], "truncatedfront"))
                            domeMode = DOME_TRUNCATED_FRONT;

                        else if (!strcmp(argv[i], "truncatedrear"))
                            domeMode = DOME_TRUNCATED_REAR;

                        else if (!strcmp(argv[i], "cubemap"))
                            domeMode = DOME_ENVMAP;

                        else if (!strcmp(argv[i], "sphericalpanoramic"))
                            domeMode = DOME_PANORAM_SPH;

                        else
                            printf("error: %s is not a valid dome mode.\n", argv[i]);
                    }
                    i++;
                }
                break;
            }
            default:  //not recognized
            {
                printf("Unknown argument: %s\n", argv[i++]);
                break;
            }
            }
        }
        else
        {
            i++;
        }
    }

    if ((windowWidth < kMinWindowWidth) || (windowHeight < kMinWindowHeight))
    {
        error = true;
        printf("error: window size too small.\n");
    }

    if (error )
    {
        usage(argv[0], isBlenderPlayer);
        return 0;
    }

#ifdef WIN32
    if (scr_saver_mode != SCREEN_SAVER_MODE_CONFIGURATION)
#endif
    {
        // Create the system
        if (GHOST_ISystem::createSystem() == GHOST_kSuccess) {
            GHOST_ISystem* system = GHOST_ISystem::getSystem();
            assertd(system);

            if (!fullScreenWidth || !fullScreenHeight)
                system->getMainDisplayDimensions(fullScreenWidth, fullScreenHeight);
            // process first batch of events. If the user
            // drops a file on top off the blenderplayer icon, we
            // receive an event with the filename

            system->processEvents(0);

            // this bracket is needed for app (see below) to get out
            // of scope before GHOST_ISystem::disposeSystem() is called.
            {
                int exitcode = KX_EXIT_REQUEST_NO_REQUEST;
                STR_String exitstring = "";
                GPG_Application app(system);
                bool firstTimeRunning = true;
                char filename[FILE_MAX];
                char pathname[FILE_MAX];
                char *titlename;

                get_filename(argc_py_clamped, argv, filename);
                if (filename[0])
                    BLI_path_cwd(filename);


                // fill the GlobalSettings with the first scene files
                // those may change during the game and persist after using Game Actuator
                GlobalSettings gs;

                do {
                    // Read the Blender file
                    BlendFileData *bfd;

                    // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file
                    if (exitcode == KX_EXIT_REQUEST_START_OTHER_GAME)
                    {
                        char basedpath[FILE_MAX];

                        // base the actuator filename relative to the last file
                        BLI_strncpy(basedpath, exitstring.Ptr(), sizeof(basedpath));
                        BLI_path_abs(basedpath, pathname);

                        bfd = load_game_data(basedpath);

                        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);
                        }
                    }
                    else {
                        bfd = load_game_data(BKE_appdir_program_path(), filename[0]? filename: NULL);
                    }

#if defined(DEBUG)
                    printf("Game data loaded from %s\n", filename);
#endif

                    if (!bfd) {
                        usage(argv[0], isBlenderPlayer);
                        error = true;
                        exitcode = KX_EXIT_REQUEST_QUIT_GAME;
                    }
                    else {
                        /* Setting options according to the blend file if not overriden in the command line */
#ifdef WIN32
#if !defined(DEBUG)
                        if (closeConsole) {
                            system->toggleConsole(0); // Close a console window
                        }
#endif // !defined(DEBUG)
#endif // WIN32
                        Main *maggie = bfd->main;
                        Scene *scene = bfd->curscene;
                        G.main = maggie;

                        if (firstTimeRunning) {
                            G.fileflags  = bfd->fileflags;

                            gs.matmode= scene->gm.matmode;
                            gs.glslflag= scene->gm.flag;
                        }

                        //Seg Fault; icon.c gIcons == 0
                        BKE_icons_init(1);

                        titlename = maggie->name;

                        // Check whether the game should be displayed full-screen
                        if ((!fullScreenParFound) && (!windowParFound)) {
                            // Only use file settings when command line did not override
                            if ((scene->gm.playerflag & GAME_PLAYER_FULLSCREEN)) {
                                //printf("fullscreen option found in Blender file\n");
                                fullScreen = true;
                                fullScreenWidth= scene->gm.xplay;
                                fullScreenHeight= scene->gm.yplay;
                                fullScreenFrequency= scene->gm.freqplay;
                                fullScreenBpp = scene->gm.depth;
                            }
                            else
                            {
                                fullScreen = false;
                                windowWidth = scene->gm.xplay;
                                windowHeight = scene->gm.yplay;
                            }
                        }


                        // Check whether the game should be displayed in stereo (dome included)
                        if (!stereoParFound) {
                            // Only use file settings when command line did not override
                            if (scene->gm.stereoflag == STEREO_ENABLED) {
                                stereomode = (RAS_IRasterizer::StereoMode) scene->gm.stereomode;
                                if (stereomode == RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
                                    stereoWindow = true;
                            }
                        }
                        else {
                            scene->gm.stereoflag = STEREO_ENABLED;
                        }

                        if (!samplesParFound)
                            aasamples = scene->gm.aasamples;

                        // Dome specific settings
                        if (stereoFlag == STEREO_DOME) {
                            stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
                            scene->gm.stereoflag = STEREO_DOME;
                            if (domeFov > 89)
                                scene->gm.dome.angle = domeFov;
                            if (domeTilt > -180)
                                scene->gm.dome.tilt = domeTilt;
                            if (domeMode > 0)
                                scene->gm.dome.mode = domeMode;
                            if (domeWarp) {
                                //XXX to do: convert relative to absolute path
                                domeText= BKE_text_load(G.main, domeWarp, "");
                                if (!domeText)
                                    printf("error: invalid warpdata text file - %s\n", domeWarp);
                                else
                                    scene->gm.dome.warptext = domeText;
                            }
                        }

                        //					GPG_Application app (system, maggie, startscenename);
                        app.SetGameEngineData(maggie, scene, &gs, argc, argv); /* this argc cant be argc_py_clamped, since python uses it */
                        BLI_strncpy(pathname, maggie->name, sizeof(pathname));
                        if (G.main != maggie) {
                            BLI_strncpy(G.main->name, maggie->name, sizeof(G.main->name));
                        }
#ifdef WITH_PYTHON
                        setGamePythonPath(G.main->name);
#endif
                        if (firstTimeRunning) {
                            firstTimeRunning = false;

                            if (fullScreen) {
#ifdef WIN32
                                if (scr_saver_mode == SCREEN_SAVER_MODE_SAVER)
                                {
                                    app.startScreenSaverFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
                                                                   stereoWindow, stereomode, aasamples);
                                }
                                else
#endif
                                {
                                    app.startFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
                                                        stereoWindow, stereomode, aasamples, (scene->gm.playerflag & GAME_PLAYER_DESKTOP_RESOLUTION));
                                }
                            }
                            else
                            {
#ifdef __APPLE__
                                // on Mac's we'll show the executable name instead of the 'game.blend' name
                                char tempname[1024], *appstring;
                                ::strcpy(tempname, titlename);

                                appstring = strstr(tempname, ".app/");
                                if (appstring) {
                                    appstring[2] = 0;
                                    titlename = &tempname[0];
                                }
#endif
                                // Strip the path so that we have the name of the game file
                                STR_String path = titlename;
#ifndef WIN32
                                vector<STR_String> parts = path.Explode('/');
#else  // WIN32
                                vector<STR_String> parts = path.Explode('\\');
#endif // WIN32                        
                                STR_String title;
                                if (parts.size()) {
                                    title = parts[parts.size()-1];
                                    parts = title.Explode('.');
                                    if (parts.size() > 1)
                                    {
                                        title = parts[0];
                                    }
                                }
                                else {
                                    title = "blenderplayer";
                                }
#ifdef WIN32
                                if (scr_saver_mode == SCREEN_SAVER_MODE_PREVIEW)
                                {
                                    app.startScreenSaverPreview(scr_saver_hwnd, stereoWindow, stereomode, aasamples);
                                }
                                else
#endif
                                {
                                    if (parentWindow != 0)
                                        app.startEmbeddedWindow(title, parentWindow, stereoWindow, stereomode, aasamples);
                                    else
                                        app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight,
                                                        stereoWindow, stereomode, aasamples);

                                    if (SYS_GetCommandLineInt(syshandle, "nomipmap", 0)) {
                                        GPU_set_mipmap(0);
                                    }

                                    GPU_set_anisotropic(U.anisotropic_filter);
                                    GPU_set_gpu_mipmapping(U.use_gpu_mipmap);
                                }
                            }
                        }
                        else {
                            app.StartGameEngine(stereomode);
                            exitcode = KX_EXIT_REQUEST_NO_REQUEST;
                        }

                        // Add the application as event consumer
                        system->addEventConsumer(&app);

                        // Enter main loop
                        bool run = true;
                        char *python_main = NULL;
                        pynextframestate.state = NULL;
                        pynextframestate.func = NULL;
#ifdef WITH_PYTHON
                        python_main = KX_GetPythonMain(scene);
#endif // WITH_PYTHON
                        if (python_main) {
                            char *python_code = KX_GetPythonCode(maggie, python_main);
                            if (python_code) {
#ifdef WITH_PYTHON
                                gpg_nextframestate.system = system;
                                gpg_nextframestate.app = &app;
                                gpg_nextframestate.gs = &gs;
                                pynextframestate.state = &gpg_nextframestate;
                                pynextframestate.func = &GPG_PyNextFrame;

                                printf("Yielding control to Python script '%s'...\n", python_main);
                                PyRun_SimpleString(python_code);
                                printf("Exit Python script '%s'\n", python_main);
#endif // WITH_PYTHON
                                MEM_freeN(python_code);
                            }
                            else {
                                fprintf(stderr, "ERROR: cannot yield control to Python: no Python text data block named '%s'\n", python_main);
                            }
                        }
                        else {
                            while (run) {
                                run = GPG_NextFrame(system, &app, exitcode, exitstring, &gs);
                            }
                        }
                        app.StopGameEngine();

                        /* 'app' is freed automatic when out of scope.
                         * removal is needed else the system will free an already freed value */
                        system->removeEventConsumer(&app);

                        BLO_blendfiledata_free(bfd);
                        /* G.main == bfd->main, it gets referenced in free_nodesystem so we can't have a dangling pointer */
                        G.main = NULL;
                        if (python_main) MEM_freeN(python_main);
                    }
                } while (exitcode == KX_EXIT_REQUEST_RESTART_GAME || exitcode == KX_EXIT_REQUEST_START_OTHER_GAME);
            }

            // Seg Fault; icon.c gIcons == 0
            BKE_icons_free();

            // Dispose the system
            GHOST_ISystem::disposeSystem();
        }
        else {
            error = true;
            printf("error: couldn't create a system.\n");
        }
    }

    /* refer to WM_exit_ext() and free_blender(),
     * these are not called in the player but we need to match some of there behavior here,
     * if the order of function calls or blenders state isn't matching that of blender proper,
     * we may get troubles later on */

    free_nodesystem();

    // Cleanup
    RNA_exit();
    BLF_exit();

#ifdef WITH_INTERNATIONAL
    BLF_free_unifont();
    BLF_free_unifont_mono();
    BLF_lang_free();
#endif

    IMB_exit();
    BKE_images_exit();
    DAG_exit();
    IMB_moviecache_destruct();

    SYS_DeleteSystem(syshandle);

    int totblock= MEM_get_memory_blocks_in_use();
    if (totblock!=0) {
        printf("Error Totblock: %d\n",totblock);
        MEM_set_error_callback(mem_error_cb);
        MEM_printmemlist();
    }

    BKE_tempdir_session_purge();

    return error ? -1 : 0;
}
示例#25
0
void CParser::NextSym()
{
	// sets the global variable sym to the next symbol, and
	// if it is an operator
	//   sets the global variable opkind to the kind of operator
	// if it is a constant
	//   sets the global variable constkind to the kind of operator
	// if it is a reference to a cell
	//   sets the global variable cellcoord to the kind of operator

	errmsg = NULL;
	while (ch == ' ' || ch == 0x9)
		NextCh();

	switch (ch) {
		case '(':
			sym = lbracksym; NextCh();
			break;
		case ')':
			sym = rbracksym; NextCh();
			break;
		case ',':
			sym = commasym; NextCh();
			break;
		case '%' :
			sym = opsym; opkind = OPmodulus; NextCh();
			break;
		case '+' :
			sym = opsym; opkind = OPplus; NextCh();
			break;
		case '-' :
			sym = opsym; opkind = OPminus; NextCh();
			break;
		case '*' :
			sym = opsym; opkind = OPtimes; NextCh();
			break;
		case '/' :
			sym = opsym; opkind = OPdivide; NextCh();
			break;
		case '&' :
			sym = opsym; opkind = OPand; NextCh(); TermChar('&');
			break;
		case '|' :
			sym = opsym; opkind = OPor; NextCh(); TermChar('|');
			break;
		case '=' :
			sym = opsym; opkind = OPequal; NextCh(); TermChar('=');
			break;
		case '!' :
			sym = opsym;
			NextCh();
			if (ch == '=')
			{
				opkind = OPunequal;
				NextCh();
			}
			else
			{
				opkind = OPnot;
			}
			break;
		case '>':
			sym = opsym;
			NextCh();
			if (ch == '=')
			{
				opkind = OPgreaterequal;
				NextCh();
			}
			else
			{
				opkind = OPgreater;
			}
			break;
		case '<':
			sym = opsym;
			NextCh();
			if (ch == '=') {
				opkind = OPlessequal;
				NextCh();
			} else {
				opkind = OPless;
			}
			break;
		case '\"' :
		{
			int start;
			sym = constsym;
			constkind = stringtype;
			NextCh();
			start = chcount;
			while ((ch != '\"') && (ch != 0x0))
				NextCh();
			GrabRealString(start);
			TermChar('\"');	// check for eol before '\"'
			break;
		}
		case 0x0: sym = eolsym; break;
		default:
		{
			int start;
			start = chcount;
			DigRep();
			if ((start != chcount) || (ch == '.')) { // number
				sym = constsym;
				if (ch == '.') {
					constkind = floattype;
					NextCh();
					DigRep();
				}
				else constkind = inttype;
				if ((ch == 'e') || (ch == 'E')) {
					int mark;
					constkind = floattype;
					NextCh();
					if ((ch == '+') || (ch == '-')) NextCh();
					mark = chcount;
					DigRep();
					if (mark == chcount) {
						ScanError("Number expected after 'E'");
						return;
					}
				}
				GrabString(start);
			} else if (((ch >= 'a') && (ch <= 'z'))
			           || ((ch >= 'A') && (ch <= 'Z')))
			{ // reserved word?

				start = chcount;
				CharRep();
				GrabString(start);
				if (!strcasecmp(const_as_string, "SUM")) {
					sym = sumsym;
				}
				else if (!strcasecmp(const_as_string, "NOT")) {
					sym = opsym;
					opkind = OPnot;
				}
				else if (!strcasecmp(const_as_string, "AND")) {
					sym = opsym; opkind = OPand;
				}
				else if (!strcasecmp(const_as_string, "OR")) {
					sym = opsym; opkind = OPor;
				}
				else if (!strcasecmp(const_as_string, "IF"))
					sym = ifsym;
				else if (!strcasecmp(const_as_string, "WHOMADE"))
					sym = whocodedsym;
				else if (!strcasecmp(const_as_string, "FALSE")) {
					sym = constsym; constkind = booltype; boolvalue = false;
				} else if (!strcasecmp(const_as_string, "TRUE")) {
					sym = constsym; constkind = booltype; boolvalue = true;
				} else {
					sym = idsym;
					//STR_String str;
					//str.Format("'%s' makes no sense here", (const char*)funstr);
					//ScanError(str);
				}
			} else { // unknown symbol
				STR_String str;
				str.Format("Unexpected character '%c'", ch);
				NextCh();
				ScanError(str);
				return;
			}
		}
	}
}
示例#26
0
bool GHOST_EventPrinter::processEvent(GHOST_IEvent* event)
{
	bool handled = true;
	
	GHOST_ASSERT(event, "event==0");

	if (event->getType() == GHOST_kEventWindowUpdate) return false;

	std::cout << "\nGHOST_EventPrinter::processEvent, time: " << (GHOST_TInt32)event->getTime() << ", type: ";
	switch (event->getType()) {
	case GHOST_kEventUnknown:
		std::cout << "GHOST_kEventUnknown"; handled = false;	
		break;

	case GHOST_kEventButtonUp:
		{
		GHOST_TEventButtonData* buttonData = (GHOST_TEventButtonData*)((GHOST_IEvent*)event)->getData();
		std::cout << "GHOST_kEventCursorButtonUp, button: " << buttonData->button;
		}
		break;
	case GHOST_kEventButtonDown:
		{
		GHOST_TEventButtonData* buttonData = (GHOST_TEventButtonData*)((GHOST_IEvent*)event)->getData();
		std::cout << "GHOST_kEventButtonDown, button: " << buttonData->button;
		}
		break;

	case GHOST_kEventWheel:
		{
		GHOST_TEventWheelData* wheelData = (GHOST_TEventWheelData*)((GHOST_IEvent*)event)->getData();
		std::cout << "GHOST_kEventWheel, z: " << wheelData->z;
		}
		break;

	case GHOST_kEventCursorMove:
		{
		GHOST_TEventCursorData* cursorData = (GHOST_TEventCursorData*)((GHOST_IEvent*)event)->getData();
		std::cout << "GHOST_kEventCursorMove, (x,y): (" << cursorData->x << "," << cursorData->y << ")";
		}
		break;

	case GHOST_kEventKeyUp:
		{
		GHOST_TEventKeyData* keyData = (GHOST_TEventKeyData*)((GHOST_IEvent*)event)->getData();
		STR_String str;
		getKeyString(keyData->key, str);
		std::cout << "GHOST_kEventKeyUp, key: " << str.Ptr();
		}
		break;
	case GHOST_kEventKeyDown:
		{
		GHOST_TEventKeyData* keyData = (GHOST_TEventKeyData*)((GHOST_IEvent*)event)->getData();
		STR_String str;
		getKeyString(keyData->key, str);
		std::cout << "GHOST_kEventKeyDown, key: " << str.Ptr();
		}
		break;
			
	case GHOST_kEventDraggingEntered:
		{
			GHOST_TEventDragnDropData* dragnDropData = (GHOST_TEventDragnDropData*)((GHOST_IEvent*)event)->getData();
			std::cout << "GHOST_kEventDraggingEntered, dragged object type : " << dragnDropData->dataType;
			std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y;
		}
		break;
			
	case GHOST_kEventDraggingUpdated:
		{
			GHOST_TEventDragnDropData* dragnDropData = (GHOST_TEventDragnDropData*)((GHOST_IEvent*)event)->getData();
			std::cout << "GHOST_kEventDraggingUpdated, dragged object type : " << dragnDropData->dataType;
			std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y;
		}
		break;

	case GHOST_kEventDraggingExited:
		{
			GHOST_TEventDragnDropData* dragnDropData = (GHOST_TEventDragnDropData*)((GHOST_IEvent*)event)->getData();
			std::cout << "GHOST_kEventDraggingExited, dragged object type : " << dragnDropData->dataType;
		}
		break;
	
	case GHOST_kEventDraggingDropDone:
		{
			GHOST_TEventDragnDropData* dragnDropData = (GHOST_TEventDragnDropData*)((GHOST_IEvent*)event)->getData();
			std::cout << "GHOST_kEventDraggingDropDone,";
			std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y;
			switch (dragnDropData->dataType) {
				case GHOST_kDragnDropTypeString:
					std::cout << " type : GHOST_kDragnDropTypeString,";
					std::cout << "\n  String received = " << (char*)dragnDropData->data;
					break;
				case GHOST_kDragnDropTypeFilenames:
				{
					GHOST_TStringArray *strArray = (GHOST_TStringArray*)dragnDropData->data;
					int i;
					std::cout << " type : GHOST_kDragnDropTypeFilenames,";
					std::cout << "\n  Received " << strArray->count << " filename" << (strArray->count > 1 ? "s:" : ":");
					for (i=0;i<strArray->count;i++)
						std::cout << "\n	File[" << i << "] : " << strArray->strings[i];
				}
					break;
				default:
					break;
			}
		}
		break;

	case GHOST_kEventOpenMainFile:
		{
			GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData();
			
			if (eventData)
				std::cout << "GHOST_kEventOpenMainFile for path : " << (char*)eventData;
			else
				std::cout << "GHOST_kEventOpenMainFile with no path specified!!";
		}
		break;
			
	case GHOST_kEventQuit:
		std::cout << "GHOST_kEventQuit"; 
		break;
	case GHOST_kEventWindowClose:
		std::cout << "GHOST_kEventWindowClose"; 
		break;
	case GHOST_kEventWindowActivate:
		std::cout << "GHOST_kEventWindowActivate"; 
		break;
	case GHOST_kEventWindowDeactivate:
		std::cout << "GHOST_kEventWindowDeactivate"; 
		break;
	case GHOST_kEventWindowUpdate:
		std::cout << "GHOST_kEventWindowUpdate"; 
		break;
	case GHOST_kEventWindowSize:
		std::cout << "GHOST_kEventWindowSize"; 
		break;

	default:
		std::cout << "not found"; handled = false; 
		break;
	}
	return handled;
}
示例#27
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 *scene= 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 = scene->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.sce, sizeof(oldsce));
#ifndef DISABLE_PYTHON
	resetGamePythonPath(); // need this so running a second time wont use an old blendfiles path
	setGamePythonPath(G.sce);

	// 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);

	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 game2ipo = (SYS_GetCommandLineInt(syshandle, "game2ipo", 0) != 0);
		bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0);
		bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0);
		bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0);
		// create the canvas, rasterizer and rendertools
		RAS_ICanvas* canvas = new KX_BlenderCanvas(win, area_rect);
		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->SetNetworkDevice(networkdevice);
		ketsjiengine->SetUseFixedTime(usefixed);
		ketsjiengine->SetTimingDisplay(frameRate, profile, properties);

#ifndef DISABLE_PYTHON
		CValue::SetDeprecationWarnings(nodepwarnings);
#endif

		//lock frame and camera enabled - storing global values
		int tmp_lay= scene->lay;
		Object *tmp_camera = scene->camera;

		if (v3d->scenelock==0){
			scene->lay= v3d->lay;
			scene->camera= v3d->camera;
		}

		// some blender stuff
		MT_CmMatrix4x4 projmat;
		MT_CmMatrix4x4 viewmat;
		float camzoom;
		int i;

		for (i = 0; i < 16; i++)
		{
			float *viewmat_linear= (float*) rv3d->viewmat;
			viewmat.setElem(i, viewmat_linear[i]);
		}
		for (i = 0; i < 16; i++)
		{
			float *projmat_linear= (float*) rv3d->winmat;
			projmat.setElem(i, projmat_linear[i]);
		}
		
		if(rv3d->persp==RV3D_CAMOB) {
			if(scene->gm.framing.type == SCE_GAMEFRAMING_BARS) { /* Letterbox */
				camzoom = 1.0f;
			}
			else {
				camzoom = (1.41421 + (rv3d->camzoom / 50.0));
				camzoom *= camzoom;
				camzoom = 4.0 / 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[240];
			// 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_convertstringcode(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_convertstringcode(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.sce, blenderdata->name, sizeof(G.sce));
					BLI_strncpy(pathname, blenderdata->name, sizeof(pathname));
#ifndef DISABLE_PYTHON
					setGamePythonPath(G.sce);
#endif
				}
			}
			// else forget it, we can't find it
			else
			{
				exitrequested = KX_EXIT_REQUEST_QUIT_GAME;
			}
		}
		
		Scene *blscene = NULL;
		if (!bfd)
		{
			blscene = (Scene*) blenderdata->scene.first;
			for (Scene *sce= (Scene*) blenderdata->scene.first; sce; sce= (Scene*) sce->id.next)
			{
				if (startscenename == (sce->id.name+2))
				{
					blscene = sce;
					break;
				}
			}
		} else {
			blscene = bfd->curscene;
		}

		if (blscene)
		{
			int startFrame = blscene->r.cfra;
			ketsjiengine->SetGame2IpoMode(game2ipo,startFrame);
			
			// Quad buffered needs a special window.
			if(blscene->gm.stereoflag == STEREO_ENABLED){
				if (blscene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
					rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) blscene->gm.stereomode);
			}

			rasterizer->SetBackColor(blscene->gm.framing.col[0], blscene->gm.framing.col[1], blscene->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(projmat);
				ketsjiengine->SetCameraOverrideViewMatrix(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);
			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(blscene->gm.matmode == GAME_MAT_GLSL)
				usemat = false;

            if(usemat && (blscene->gm.matmode != GAME_MAT_TEXFACE))
				sceneconverter->SetMaterials(true);
			if(useglslmat && (blscene->gm.matmode == GAME_MAT_GLSL))
				sceneconverter->SetGLSLMaterials(true);
					
			KX_Scene* startscene = new KX_Scene(keyboarddevice,
				mousedevice,
				networkdevice,
				startscenename,
				blscene);

#ifndef DISABLE_PYTHON
			// some python things
			PyObject* dictionaryobject = initGamePythonScripting("Ketsji", psl_Lowest, blenderdata);
			ketsjiengine->SetPyNamespace(dictionaryobject);
			initRasterizer(rasterizer, canvas);
			PyObject *gameLogic = initGameLogic(ketsjiengine, startscene);
			PyDict_SetItemString(PyModule_GetDict(gameLogic), "globalDict", pyGlobalDict); // Same as importing the module.
			PyObject *gameLogic_keys = PyDict_Keys(PyModule_GetDict(gameLogic));
			PyDict_SetItemString(dictionaryobject, "GameLogic", gameLogic); // Same as importing the module.
			
			initGameKeys();
			initPythonConstraintBinding();
			initMathutils();
			initGeometry();
			initBGL();
#ifdef WITH_FFMPEG
			initVideoTexture();
#endif
#endif // DISABLE_PYTHON

			//initialize Dome Settings
			if(blscene->gm.stereoflag == STEREO_DOME)
				ketsjiengine->InitDome(blscene->gm.dome.res, blscene->gm.dome.mode, blscene->gm.dome.angle, blscene->gm.dome.resbuf, blscene->gm.dome.tilt, blscene->gm.dome.warptext);

			// initialize 3D Audio Settings
			AUD_set3DSetting(AUD_3DS_SPEED_OF_SOUND, blscene->audio.speed_of_sound);
			AUD_set3DSetting(AUD_3DS_DOPPLER_FACTOR, blscene->audio.doppler_factor);
			AUD_set3DSetting(AUD_3DS_DISTANCE_MODEL, blscene->audio.distance_model);

			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( (((double) blscene->r.frs_sec) / blscene->r.frs_sec_base) );
				
				// the mainloop
				printf("\nBlender Game Engine Started\n\n");
				while (!exitrequested)
				{
					// first check if we want to exit
					exitrequested = ketsjiengine->GetExitCode();
					
					// kick the engine
					bool render = ketsjiengine->NextFrame(); // XXX 2.5 Bug, This is never true! FIXME-  Campbell
					
					if (render)
					{
						// render the frame
						ketsjiengine->Render();
					}
					
					wm_window_process_events_nosleep(C);
					
					// 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 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);
					}
					
				}
				printf("\nBlender Game Engine Finished\n\n");
				exitstring = ketsjiengine->GetExitString();


				// when exiting the mainloop
#ifndef DISABLE_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
				int listIndex;
				PyObject *gameLogic_keys_new = PyDict_Keys(PyModule_GetDict(gameLogic));
				for (listIndex=0; listIndex < PyList_Size(gameLogic_keys_new); 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();
#ifndef DISABLE_PYTHON
				exitGamePythonScripting();
#endif
				networkdevice->Disconnect();
			}
			if (sceneconverter)
			{
				delete sceneconverter;
				sceneconverter = NULL;
			}

#ifndef DISABLE_PYTHON
			Py_DECREF(gameLogic_keys);
			gameLogic_keys = NULL;
#endif
		}
		//lock frame and camera enabled - restoring global values
		if (v3d->scenelock==0){
			scene->lay= tmp_lay;
			scene->camera= tmp_camera;
		}

		// 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;
                }
	
	} while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME);
	
	if (bfd) BLO_blendfiledata_free(bfd);

	BLI_strncpy(G.sce, oldsce, sizeof(G.sce));

#ifndef DISABLE_PYTHON
	Py_DECREF(pyGlobalDict);

	// Release Python's GIL
	PyGILState_Release(gilstate);
#endif

}
示例#28
0
/* note, this is called as a python getset */
int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAttributeDef *attrdef)
{
	PyObjectPlus *ref= (BGE_PROXY_REF(self_py));
	char* ptr = (attrdef->m_usePtr) ? (char*)BGE_PROXY_PTR(self_py) : (char*)ref;
	if (ref==NULL || !ref->py_is_valid() || ptr==NULL) {
		PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
		return PY_SET_ATTR_FAIL;
	}

	void *undoBuffer = NULL;
	void *sourceBuffer = NULL;
	size_t bufferSize = 0;
	PyObject *item = NULL;	// to store object that must be dereferenced in case of error
	PyObject *list = NULL;	// to store object that must be dereferenced in case of error
	
	ptr += attrdef->m_offset;
	if (attrdef->m_length > 1)
	{
		if (!PySequence_Check(value)) 
		{
			PyErr_Format(PyExc_TypeError, "expected a sequence for attribute \"%s\"", attrdef->m_name);
			return PY_SET_ATTR_FAIL;
		}
		if (PySequence_Size(value) != attrdef->m_length)
		{
			PyErr_Format(PyExc_TypeError, "incorrect number of elements in sequence for attribute \"%s\"", attrdef->m_name);
			return PY_SET_ATTR_FAIL;
		}
		switch (attrdef->m_type) 
		{
		case KX_PYATTRIBUTE_TYPE_FUNCTION:
			if (attrdef->m_setFunction == NULL) 
			{
				PyErr_Format(PyExc_AttributeError, "function attribute without function for attribute \"%s\", report to blender.org", attrdef->m_name);
				return PY_SET_ATTR_FAIL;
			}
			return (*attrdef->m_setFunction)(ref, attrdef, value);
		case KX_PYATTRIBUTE_TYPE_BOOL:
			bufferSize = sizeof(bool);
			break;
		case KX_PYATTRIBUTE_TYPE_SHORT:
			bufferSize = sizeof(short int);
			break;
		case KX_PYATTRIBUTE_TYPE_ENUM:
		case KX_PYATTRIBUTE_TYPE_INT:
			bufferSize = sizeof(int);
			break;
		case KX_PYATTRIBUTE_TYPE_FLOAT:
			bufferSize = sizeof(float);
			break;
		default:
			// should not happen
			PyErr_Format(PyExc_AttributeError, "Unsupported attribute type for attribute \"%s\", report to blender.org", attrdef->m_name);
			return PY_SET_ATTR_FAIL;
		}
		// let's implement a smart undo method
		bufferSize *= attrdef->m_length;
		undoBuffer = malloc(bufferSize);
		sourceBuffer = ptr;
		if (undoBuffer)
		{
			memcpy(undoBuffer, sourceBuffer, bufferSize);
		}
		for (int i=0; i<attrdef->m_length; i++)
		{
			item = PySequence_GetItem(value, i); /* new ref */
			switch (attrdef->m_type) 
			{
			case KX_PYATTRIBUTE_TYPE_BOOL:
				{
					bool *var = reinterpret_cast<bool*>(ptr);
					ptr += sizeof(bool);
					if (PyLong_Check(item)) 
					{
						*var = (PyLong_AsLong(item) != 0);
					} 
					else if (PyBool_Check(item))
					{
						*var = (item == Py_True);
					}
					else
					{
						PyErr_Format(PyExc_TypeError, "expected an integer or a bool for attribute \"%s\"", attrdef->m_name);
						goto UNDO_AND_ERROR;
					}
					break;
				}
			case KX_PYATTRIBUTE_TYPE_SHORT:
				{
					short int *var = reinterpret_cast<short int*>(ptr);
					ptr += sizeof(short int);
					if (PyLong_Check(item)) 
					{
						int val = PyLong_AsLong(item);
						if (attrdef->m_clamp)
						{
							if (val < attrdef->m_imin)
								val = attrdef->m_imin;
							else if (val > attrdef->m_imax)
								val = attrdef->m_imax;
						}
						else if (val < attrdef->m_imin || val > attrdef->m_imax)
						{
							PyErr_Format(PyExc_ValueError, "item value out of range for attribute \"%s\"", attrdef->m_name);
							goto UNDO_AND_ERROR;
						}
						*var = (short int)val;
					}
					else
					{
						PyErr_Format(PyExc_TypeError, "expected an integer for attribute \"%s\"", attrdef->m_name);
						goto UNDO_AND_ERROR;
					}
					break;
				}
			case KX_PYATTRIBUTE_TYPE_ENUM:
				// enum are equivalent to int, just make sure that the field size matches:
				if (sizeof(int) != attrdef->m_size)
				{
					PyErr_Format(PyExc_AttributeError, "Size check error for attribute, \"%s\", report to blender.org", attrdef->m_name);
					goto UNDO_AND_ERROR;
				}
				// walkthrough
			case KX_PYATTRIBUTE_TYPE_INT:
				{
					int *var = reinterpret_cast<int*>(ptr);
					ptr += sizeof(int);
					if (PyLong_Check(item)) 
					{
						int val = PyLong_AsLong(item);
						if (attrdef->m_clamp)
						{
							if (val < attrdef->m_imin)
								val = attrdef->m_imin;
							else if (val > attrdef->m_imax)
								val = attrdef->m_imax;
						}
						else if (val < attrdef->m_imin || val > attrdef->m_imax)
						{
							PyErr_Format(PyExc_ValueError, "item value out of range for attribute \"%s\"", attrdef->m_name);
							goto UNDO_AND_ERROR;
						}
						*var = (int)val;
					}
					else
					{
						PyErr_Format(PyExc_TypeError, "expected an integer for attribute \"%s\"", attrdef->m_name);
						goto UNDO_AND_ERROR;
					}
					break;
				}
			case KX_PYATTRIBUTE_TYPE_FLOAT:
				{
					float *var = reinterpret_cast<float*>(ptr);
					ptr += sizeof(float);
					float val = PyFloat_AsDouble(item);
					if (val == -1.0f && PyErr_Occurred())
					{
						PyErr_Format(PyExc_TypeError, "expected a float for attribute \"%s\"", attrdef->m_name);
						goto UNDO_AND_ERROR;
					}
					else if (attrdef->m_clamp)
					{
						if (val < attrdef->m_fmin)
							val = attrdef->m_fmin;
						else if (val > attrdef->m_fmax)
							val = attrdef->m_fmax;
					}
					else if (val < attrdef->m_fmin || val > attrdef->m_fmax)
					{
						PyErr_Format(PyExc_ValueError, "item value out of range for attribute \"%s\"", attrdef->m_name);
						goto UNDO_AND_ERROR;
					}
					*var = (float)val;
					break;
				}
			default:
				// should not happen
				PyErr_Format(PyExc_AttributeError, "type check error for attribute \"%s\", report to blender.org", attrdef->m_name);
				goto UNDO_AND_ERROR;
			}
			// finished using item, release
			Py_DECREF(item);
			item = NULL;
		}
		// no error, call check function if any
		if (attrdef->m_checkFunction != NULL)
		{
			if ((*attrdef->m_checkFunction)(ref, attrdef) != 0)
			{
				// if the checing function didnt set an error then set a generic one here so we don't set an error with no exception
				if (PyErr_Occurred()==0)
					PyErr_Format(PyExc_AttributeError, "type check error for attribute \"%s\", reasion unknown", attrdef->m_name);
				
				// post check returned an error, restore values
			UNDO_AND_ERROR:
				if (undoBuffer)
				{
					memcpy(sourceBuffer, undoBuffer, bufferSize);
					free(undoBuffer);
				}
				if (item)
					Py_DECREF(item);
				return PY_SET_ATTR_FAIL;
			}
		}
		if (undoBuffer)
			free(undoBuffer);
		return PY_SET_ATTR_SUCCESS;
	}
	else	// simple attribute value
	{
		if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_FUNCTION)
		{
			if (attrdef->m_setFunction == NULL)
			{
				PyErr_Format(PyExc_AttributeError, "function attribute without function \"%s\", report to blender.org", attrdef->m_name);
				return PY_SET_ATTR_FAIL;
			}
			return (*attrdef->m_setFunction)(ref, attrdef, value);
		}
		if (attrdef->m_checkFunction != NULL || attrdef->m_type == KX_PYATTRIBUTE_TYPE_VECTOR)
		{
			// post check function is provided, prepare undo buffer
			sourceBuffer = ptr;
			switch (attrdef->m_type) 
			{
			case KX_PYATTRIBUTE_TYPE_BOOL:
				bufferSize = sizeof(bool);
				break;
			case KX_PYATTRIBUTE_TYPE_SHORT:
				bufferSize = sizeof(short);
				break;
			case KX_PYATTRIBUTE_TYPE_ENUM:
			case KX_PYATTRIBUTE_TYPE_FLAG:
			case KX_PYATTRIBUTE_TYPE_CHAR:
				bufferSize = attrdef->m_size;
				break;
			case KX_PYATTRIBUTE_TYPE_INT:
				bufferSize = sizeof(int);
				break;
			case KX_PYATTRIBUTE_TYPE_FLOAT:
				bufferSize = sizeof(float);
				if (attrdef->m_imax)
					bufferSize *= attrdef->m_imax;
				if (attrdef->m_imin)
					bufferSize *= attrdef->m_imin;
				break;
			case KX_PYATTRIBUTE_TYPE_STRING:
				sourceBuffer = reinterpret_cast<STR_String*>(ptr)->Ptr();
				if (sourceBuffer)
					bufferSize = strlen(reinterpret_cast<char*>(sourceBuffer))+1;
				break;
			case KX_PYATTRIBUTE_TYPE_VECTOR:
				bufferSize = sizeof(MT_Vector3);
				break;
			default:
				PyErr_Format(PyExc_AttributeError, "unknown type for attribute \"%s\", report to blender.org", attrdef->m_name);
				return PY_SET_ATTR_FAIL;
			}
			if (bufferSize)
			{
				undoBuffer = malloc(bufferSize);
				if (undoBuffer)
				{
					memcpy(undoBuffer, sourceBuffer, bufferSize);
				}
			}
		}
			
		switch (attrdef->m_type) 
		{
		case KX_PYATTRIBUTE_TYPE_BOOL:
			{
				bool *var = reinterpret_cast<bool*>(ptr);
				if (PyLong_Check(value)) 
				{
					*var = (PyLong_AsLong(value) != 0);
				} 
				else if (PyBool_Check(value))
				{
					*var = (value == Py_True);
				}
				else
				{
					PyErr_Format(PyExc_TypeError, "expected an integer or a bool for attribute \"%s\"", attrdef->m_name);
					goto FREE_AND_ERROR;
				}
				break;
			}
		case KX_PYATTRIBUTE_TYPE_FLAG:
			{
				bool bval;
				if (PyLong_Check(value)) 
				{
					bval = (PyLong_AsLong(value) != 0);
				} 
				else if (PyBool_Check(value))
				{
					bval = (value == Py_True);
				}
				else
				{
					PyErr_Format(PyExc_TypeError, "expected an integer or a bool for attribute \"%s\"", attrdef->m_name);
					goto FREE_AND_ERROR;
				}
				if (attrdef->m_imax)
					bval = !bval;
				switch (attrdef->m_size) {
				case 1:
					{
						unsigned char *val = reinterpret_cast<unsigned char*>(ptr);
						*val = (*val & ~attrdef->m_imin) | ((bval)?attrdef->m_imin:0);
						break;
					}
				case 2:
					{
						unsigned short *val = reinterpret_cast<unsigned short*>(ptr);
						*val = (*val & ~attrdef->m_imin) | ((bval)?attrdef->m_imin:0);
						break;
					}
				case 4:
					{
						unsigned int *val = reinterpret_cast<unsigned int*>(ptr);
						*val = (*val & ~attrdef->m_imin) | ((bval)?attrdef->m_imin:0);
						break;
					}
				default:
					PyErr_Format(PyExc_TypeError, "internal error: unsupported flag field \"%s\"", attrdef->m_name);
					goto FREE_AND_ERROR;
				}
				break;
			}
		case KX_PYATTRIBUTE_TYPE_SHORT:
			{
				short int *var = reinterpret_cast<short int*>(ptr);
				if (PyLong_Check(value)) 
				{
					int val = PyLong_AsLong(value);
					if (attrdef->m_clamp)
					{
						if (val < attrdef->m_imin)
							val = attrdef->m_imin;
						else if (val > attrdef->m_imax)
							val = attrdef->m_imax;
					}
					else if (val < attrdef->m_imin || val > attrdef->m_imax)
					{
						PyErr_Format(PyExc_ValueError, "value out of range for attribute \"%s\"", attrdef->m_name);
						goto FREE_AND_ERROR;
					}
					*var = (short int)val;
				}
				else
				{
					PyErr_Format(PyExc_TypeError, "expected an integer for attribute \"%s\"", attrdef->m_name);
					goto FREE_AND_ERROR;
				}
				break;
			}
		case KX_PYATTRIBUTE_TYPE_ENUM:
			// enum are equivalent to int, just make sure that the field size matches:
			if (sizeof(int) != attrdef->m_size)
			{
				PyErr_Format(PyExc_AttributeError, "attribute size check error for attribute \"%s\", report to blender.org", attrdef->m_name);
				goto FREE_AND_ERROR;
			}
			// walkthrough
		case KX_PYATTRIBUTE_TYPE_INT:
			{
				int *var = reinterpret_cast<int*>(ptr);
				if (PyLong_Check(value)) 
				{
					int val = PyLong_AsLong(value);
					if (attrdef->m_clamp)
					{
						if (val < attrdef->m_imin)
							val = attrdef->m_imin;
						else if (val > attrdef->m_imax)
							val = attrdef->m_imax;
					}
					else if (val < attrdef->m_imin || val > attrdef->m_imax)
					{
						PyErr_Format(PyExc_ValueError, "value out of range for attribute \"%s\"", attrdef->m_name);
						goto FREE_AND_ERROR;
					}
					*var = (int)val;
				}
				else
				{
					PyErr_Format(PyExc_TypeError, "expected an integer for attribute \"%s\"", attrdef->m_name);
					goto FREE_AND_ERROR;
				}
				break;
			}
		case KX_PYATTRIBUTE_TYPE_FLOAT:
			{
				float *var = reinterpret_cast<float*>(ptr);
				if (attrdef->m_imin != 0) 
				{
					if (attrdef->m_size != attrdef->m_imin*attrdef->m_imax*sizeof(float)) 
					{
						PyErr_Format(PyExc_TypeError, "internal error: incorrect field size for attribute \"%s\"", attrdef->m_name);
						goto FREE_AND_ERROR;
					}
					if (!PySequence_Check(value) || PySequence_Size(value) != attrdef->m_imin) 
					{
						PyErr_Format(PyExc_TypeError, "expected a sequence of [%d][%d] floats for attribute \"%s\"", attrdef->m_imin, attrdef->m_imax, attrdef->m_name);
						goto FREE_AND_ERROR;
					}
					for (int i=0; i<attrdef->m_imin; i++)
					{
						PyObject *list = PySequence_GetItem(value, i); /* new ref */
						if (!PySequence_Check(list) || PySequence_Size(list) != attrdef->m_imax) 
						{
							PyErr_Format(PyExc_TypeError, "expected a sequence of [%d][%d] floats for attribute \"%s\"", attrdef->m_imin, attrdef->m_imax, attrdef->m_name);
							goto RESTORE_AND_ERROR;
						}
						for (int j=0; j<attrdef->m_imax; j++)
						{
							item = PySequence_GetItem(list, j); /* new ref */
							if (!py_check_attr_float(var, item, attrdef))
							{
								PyErr_Format(PyExc_TypeError, "expected a sequence of [%d][%d] floats for attribute \"%s\"", attrdef->m_imin, attrdef->m_imax, attrdef->m_name);
								goto RESTORE_AND_ERROR;
							}
							Py_DECREF(item);
							item = NULL;
							++var;
						}
						Py_DECREF(list);
						list = NULL;
					}
				} 
				else if (attrdef->m_imax != 0) 
				{
					if (attrdef->m_size != attrdef->m_imax*sizeof(float)) 
					{
						PyErr_Format(PyExc_TypeError, "internal error: incorrect field size for attribute \"%s\"", attrdef->m_name);
						goto FREE_AND_ERROR;
					}
					if (!PySequence_Check(value) || PySequence_Size(value) != attrdef->m_imax) 
					{
						PyErr_Format(PyExc_TypeError, "expected a sequence of [%d] floats for attribute \"%s\"", attrdef->m_imax, attrdef->m_name);
						goto FREE_AND_ERROR;
					}
					for (int i=0; i<attrdef->m_imax; i++)
					{
						item = PySequence_GetItem(value, i); /* new ref */
						if (!py_check_attr_float(var, item, attrdef))
						{
							goto RESTORE_AND_ERROR;
						}
						Py_DECREF(item);
						item = NULL;
						++var;
					}
				} 
				else
				{
					if (!py_check_attr_float(var, value, attrdef))
						goto FREE_AND_ERROR;
				}
				break;
			}
		case KX_PYATTRIBUTE_TYPE_VECTOR:
			{
				if (!PySequence_Check(value) || PySequence_Size(value) != 3) 
				{
					PyErr_Format(PyExc_TypeError, "expected a sequence of 3 floats for attribute \"%s\"", attrdef->m_name);
					goto FREE_AND_ERROR;
				}
				MT_Vector3 *var = reinterpret_cast<MT_Vector3*>(ptr);
				for (int i=0; i<3; i++)
				{
					item = PySequence_GetItem(value, i); /* new ref */
					float val = PyFloat_AsDouble(item);
					Py_DECREF(item);
					item = NULL;
					if (val == -1.0f && PyErr_Occurred())
					{
						PyErr_Format(PyExc_TypeError, "expected a sequence of 3 floats for attribute \"%s\"", attrdef->m_name);
						goto RESTORE_AND_ERROR;
					}
					else if (attrdef->m_clamp)
					{
						if (val < attrdef->m_fmin)
							val = attrdef->m_fmin;
						else if (val > attrdef->m_fmax)
							val = attrdef->m_fmax;
					}
					else if (val < attrdef->m_fmin || val > attrdef->m_fmax)
					{
						PyErr_Format(PyExc_ValueError, "value out of range for attribute \"%s\"", attrdef->m_name);
						goto RESTORE_AND_ERROR;
					}
					(*var)[i] = (MT_Scalar)val;
				}
				break;
			}
		case KX_PYATTRIBUTE_TYPE_CHAR:
			{
				if (PyUnicode_Check(value)) 
				{
					Py_ssize_t val_size;
					const char *val = _PyUnicode_AsStringAndSize(value, &val_size);
					strncpy(ptr, val, attrdef->m_size);
					ptr[attrdef->m_size-1] = 0;
				}
				else
				{
					PyErr_Format(PyExc_TypeError, "expected a string for attribute \"%s\"", attrdef->m_name);
					goto FREE_AND_ERROR;
				}
				break;
			}
		case KX_PYATTRIBUTE_TYPE_STRING:
			{
				STR_String *var = reinterpret_cast<STR_String*>(ptr);
				if (PyUnicode_Check(value)) 
				{
					Py_ssize_t val_len;
					const char *val = _PyUnicode_AsStringAndSize(value, &val_len); /* XXX, should be 'const' but we do a silly trick to have a shorter string */
					if (attrdef->m_clamp)
					{
						if (val_len < attrdef->m_imin)
						{
							// can't increase the length of the string
							PyErr_Format(PyExc_ValueError, "string length too short for attribute \"%s\"", attrdef->m_name);
							goto FREE_AND_ERROR;
						}
						else if (val_len > attrdef->m_imax)
						{
							// trim the string
							var->SetLength(attrdef->m_imax);
							memcpy(var->Ptr(), val, attrdef->m_imax - 1);
							break;
						}
					} else if (val_len < attrdef->m_imin || val_len > attrdef->m_imax)
					{
						PyErr_Format(PyExc_ValueError, "string length out of range for attribute \"%s\"", attrdef->m_name);
						goto FREE_AND_ERROR;
					}
					*var = val;
				}
				else
				{
					PyErr_Format(PyExc_TypeError, "expected a string for attribute \"%s\"", attrdef->m_name);
					goto FREE_AND_ERROR;
				}
				break;
			}
		default:
			// should not happen
			PyErr_Format(PyExc_AttributeError, "unknown type for attribute \"%s\", report to blender.org", attrdef->m_name);
			goto FREE_AND_ERROR;
		}
	}
	// check if post processing is needed
	if (attrdef->m_checkFunction != NULL)
	{
		if ((*attrdef->m_checkFunction)(ref, attrdef) != 0)
		{
			// restore value
		RESTORE_AND_ERROR:
			if (undoBuffer)
			{
				if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_STRING)
				{
					// special case for STR_String: restore the string
					STR_String *var = reinterpret_cast<STR_String*>(ptr);
					*var = reinterpret_cast<char*>(undoBuffer);
				}
				else
				{
					// other field type have direct values
					memcpy(ptr, undoBuffer, bufferSize);
				}
			}
		FREE_AND_ERROR:
			if (undoBuffer)
				free(undoBuffer);
			if (list)
				Py_DECREF(list);
			if (item)
				Py_DECREF(item);
			return 1;
		}
	}
	if (undoBuffer)
		free(undoBuffer);
	return 0;
}
示例#29
0
void BL_ConvertControllers(
	struct Object* blenderobject,
	class KX_GameObject* gameobj,
	SCA_LogicManager* logicmgr,
	int activeLayerBitInfo,
	bool isInActiveLayer,
	KX_BlenderSceneConverter* converter
) {
	int uniqueint=0;
	int count = 0;
	int executePriority=0;
	bController* bcontr = (bController*)blenderobject->controllers.first;
	while (bcontr)
	{
		bcontr = bcontr->next;
		count++;
	}
	gameobj->ReserveController(count);
	bcontr = (bController*)blenderobject->controllers.first;
	while (bcontr)
	{
		SCA_IController* gamecontroller = NULL;
		switch(bcontr->type)
		{
			case CONT_LOGIC_AND:
			{
				gamecontroller = new SCA_ANDController(gameobj);
				break;
			}
			case CONT_LOGIC_OR:
			{
				gamecontroller = new SCA_ORController(gameobj);
				break;
			}
			case CONT_LOGIC_NAND:
			{
				gamecontroller = new SCA_NANDController(gameobj);
				break;
			}
			case CONT_LOGIC_NOR:
			{
				gamecontroller = new SCA_NORController(gameobj);
				break;
			}
			case CONT_LOGIC_XOR:
			{
				gamecontroller = new SCA_XORController(gameobj);
				break;
			}
			case CONT_LOGIC_XNOR:
			{
				gamecontroller = new SCA_XNORController(gameobj);
				break;
			}
			case CONT_EXPRESSION:
			{
				bExpressionCont* bexpcont = (bExpressionCont*) bcontr->data;
				STR_String expressiontext = STR_String(bexpcont->str);
				if (expressiontext.Length() > 0)
				{
					gamecontroller = new SCA_ExpressionController(gameobj,expressiontext);
				}
				break;
			}
			case CONT_PYTHON:
			{
				bPythonCont* pycont = (bPythonCont*) bcontr->data;
				SCA_PythonController* pyctrl = new SCA_PythonController(gameobj, pycont->mode);
				gamecontroller = pyctrl;
#ifdef WITH_PYTHON

				pyctrl->SetNamespace(converter->GetPyNamespace());
				
				if(pycont->mode==SCA_PythonController::SCA_PYEXEC_SCRIPT) {
					if (pycont->text)
					{
						char *buf;
						// this is some blender specific code
						buf= txt_to_buf(pycont->text);
						if (buf)
						{
							pyctrl->SetScriptText(STR_String(buf));
							pyctrl->SetScriptName(pycont->text->id.name+2);
							MEM_freeN(buf);
						}
						
					}
				}
				else {
					/* let the controller print any warnings here when importing */
					pyctrl->SetScriptText(STR_String(pycont->module)); 
					pyctrl->SetScriptName(pycont->module); /* will be something like module.func so using it as the name is OK */

					if(pycont->flag & CONT_PY_DEBUG) {
						printf("\nDebuging \"%s\", module for object %s\n\texpect worse performance.\n", pycont->module, blenderobject->id.name+2);
						pyctrl->SetDebug(true);
					}
				}
				
#endif // WITH_PYTHON

				break;
			}
			default:
			{
				
			}
		}

		if (gamecontroller)
		{
			LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
			gamecontroller->SetExecutePriority(executePriority++);
			gamecontroller->SetBookmark((bcontr->flag & CONT_PRIO) != 0);
			gamecontroller->SetState(bcontr->state_mask);
			STR_String uniquename = bcontr->name;
			uniquename += "#CONTR#";
			uniqueint++;
			CIntValue* uniqueval = new CIntValue(uniqueint);
			uniquename += uniqueval->GetText();
			uniqueval->Release();
			//unique name was never implemented for sensors and actuators, only for controllers
			//and it's producing difference in the keys for the lists: obj.controllers/sensors/actuators
			//at some point it should either be implemented globally (and saved as a separate var) or removed.
			//gamecontroller->SetName(uniquename);
			gamecontroller->SetName(bcontr->name);
			gameobj->AddController(gamecontroller);
			
			converter->RegisterGameController(gamecontroller, bcontr);

#ifdef WITH_PYTHON
			if (bcontr->type==CONT_PYTHON) {
				SCA_PythonController *pyctrl= static_cast<SCA_PythonController*>(gamecontroller);
				/* not strictly needed but gives syntax errors early on and
				 * gives more predictable performance for larger scripts */
				if(pyctrl->m_mode==SCA_PythonController::SCA_PYEXEC_SCRIPT)
					pyctrl->Compile();
				else {
					/* We cant do this because importing runs the script which could end up accessing
					 * internal BGE functions, this is unstable while we're converting the scene.
					 * This is a pitty because its useful to see errors at startup but cant help it */
					
					// pyctrl->Import();
				}
			}
#endif // WITH_PYTHON

			//done with gamecontroller
			gamecontroller->Release();
		}
		
		bcontr = bcontr->next;
	}

}