Example #1
0
void CGameFont::Initialize		(LPCSTR cShader, LPCSTR cTextureName)
{
	string_path					cTexture;

	LPCSTR _lang				= pSettings->r_string("string_table", "font_prefix");
	bool is_di					= strstr(cTextureName, "ui_font_hud_01") || 
								  strstr(cTextureName, "ui_font_hud_02") ||
								  strstr(cTextureName, "ui_font_console_02");
	if(_lang && !is_di)
		strconcat				(cTexture, cTextureName, _lang);
	else
		strcpy					(cTexture, cTextureName);

	uFlags						&=~fsValid;
	vTS.set						(1.f,1.f); // обязательно !!!

	eCurrentAlignment			= alLeft;
	vInterval.set				(1.f,1.f);

	for (int i=0; i<256; i++)	CharMap[i] = i;
	strings.reserve				(128);

	// check ini exist
	string256 fn,buf;
	strcpy		(buf,cTexture); if (strext(buf)) *strext(buf)=0;
	R_ASSERT2	(FS.exist(fn,"$game_textures$",buf,".ini"),fn);
	CInifile* ini				= CInifile::Create(fn);
	if (ini->section_exist("symbol_coords")){
		for (int i=0; i<256; i++){
			sprintf					(buf,"%03d",i);
			Fvector v				= ini->r_fvector3("symbol_coords",buf);
			TCMap[i].set			(v.x,v.y,v[2]-v[0]);
		}
		fHeight						= ini->r_float("symbol_coords","height");
	}else{
		if (ini->section_exist("char widths")){
			fHeight					= ini->r_float("char widths","height");
			int cpl					= 16;
			for (int i=0; i<256; i++){
				sprintf				(buf,"%d",i);
				float w				= ini->r_float("char widths",buf);
				TCMap[i].set		((i%cpl)*fHeight,(i/cpl)*fHeight,w);
			}
		}else{
			R_ASSERT(ini->section_exist("font_size"));
			fHeight					= ini->r_float("font_size","height");
			float width				= ini->r_float("font_size","width");
			const int cpl			= ini->r_s32	("font_size","cpl");
			for (int i=0; i<256; i++)
				TCMap[i].set		((i%cpl)*width,(i/cpl)*fHeight,width);
		}
	}
	fCurrentHeight				= fHeight;

	CInifile::Destroy			(ini);

	// Shading
	pShader.create				(cShader,cTexture);
	pGeom.create				(FVF::F_TL, RCache.Vertex.Buffer(), RCache.QuadIB);
}
Example #2
0
shared_str	ui_core::get_xml_name(LPCSTR fn)
{
	string_path				str;
	if(!is_16_9_mode()){
		sprintf_s(str, "%s", fn);
		if ( NULL==strext(fn) ) strcat(str, ".xml");
	}else{

		string_path			str_;
		if ( strext(fn) )
		{
			strcpy	(str, fn);
			*strext(str)	= 0;
			strcat	(str, "_16.xml");
		}else
			sprintf_s				(str, "%s_16", fn);

		if(NULL==FS.exist(str_, "$game_config$", "ui\\" , str) )
		{
			sprintf_s(str, "%s", fn);
			if ( NULL==strext(fn) ) strcat(str, ".xml");
		}
#ifdef DEBUG
		Msg("[16-9] get_xml_name for[%s] returns [%s]", fn, str);
#endif
	}
	return str;
}
Example #3
0
void MeshExpUtility::ExportLWO()
{
	BOOL bResult = FALSE;

	if( m_Items.empty() ){
		ELog.Msg(mtError,"Nothing selected" );
		ELog.Msg(mtError,"-------------------------------------------------------" );
		return; 
	}

	m_ObjectFlipFaces			= IsDlgButtonChecked( hPanel, IDC_OBJECT_FLIPFACES );

	string_path m_ExportName;
	m_ExportName[0]=0;
	if( !EFS.GetSaveName("$import$",m_ExportName,0,1) ){
		ELog.Msg(mtInformation,"Export cancelled" );
		ELog.Msg(mtInformation,"-------------------------------------------------------" );
		return;
	}
	if (strext(m_ExportName)) *strext(m_ExportName)=0;
	strcat(m_ExportName,".lwo");
	EConsole.StayOnTop(TRUE);
	bResult						= SaveAsLWO(m_ExportName);

	ELog.Msg					(mtInformation,bResult?". Export succesfully completed.":"! Export failed.");
	ELog.Msg					(mtInformation,"-------------------------------------------------------" );
	EConsole.StayOnTop(FALSE);
}
Example #4
0
    virtual void Execute(LPCSTR args)
    {
        string_path cfg_full_name;
        xr_strcpy(cfg_full_name, (xr_strlen(args) > 0) ? args : Console->ConfigFile);

        bool b_abs_name = xr_strlen(cfg_full_name) > 2 && cfg_full_name[1] == ':';

        if (!b_abs_name)
            FS.update_path(cfg_full_name, "$app_data_root$", cfg_full_name);

        if (strext(cfg_full_name))
            *strext(cfg_full_name) = 0;
        xr_strcat(cfg_full_name, ".ltx");

        BOOL b_allow = TRUE;
        if (FS.exist(cfg_full_name))
            b_allow = SetFileAttributes(cfg_full_name, FILE_ATTRIBUTE_NORMAL);

        if (b_allow)
        {
            IWriter* F = FS.w_open(cfg_full_name);
            CConsole::vecCMD_IT it;
            for (it = Console->Commands.begin(); it != Console->Commands.end(); it++)
                it->second->Save(F);
            FS.w_close(F);
            Msg("Config-file [%s] saved successfully", cfg_full_name);
        }
        else
            Msg("!Cannot store config file [%s]", cfg_full_name);
    }
void CSE_Visual::set_visual	   	(LPCSTR name, bool load)
{
	string_path					tmp;
    strcpy						(tmp,name);
    if (strext(tmp))		 	*strext(tmp) = 0;
	xr_strlwr					(tmp);
	visual_name					= tmp; 
}
Example #6
0
void CLevel::PrefetchSound		(LPCSTR name)
{
	// preprocess sound name
	string_path					tmp;
	strcpy_s					(tmp,name);
	xr_strlwr					(tmp);
	if (strext(tmp))			*strext(tmp)=0;
	shared_str	snd_name		= tmp;
	// find in registry
	SoundRegistryMapIt it		= sound_registry.find(snd_name);
	// if find failed - preload sound
	if (it==sound_registry.end())
		sound_registry[snd_name].create(snd_name.c_str(),st_Effect,sg_SourceType);
}
////////////////////////////////////////////////////////////////////////////
// CSE_Visual
////////////////////////////////////////////////////////////////////////////
CSE_Visual::CSE_Visual		   	(LPCSTR name)
{
	if(name)
	{
		string_path					tmp;
		strcpy						(tmp, name);
		if(strext(tmp)) 
			*strext(tmp)			=0;
		xr_strlwr					(tmp);
		visual_name					= tmp;
	}else
		visual_name					= NULL;

    startup_animation			= "$editor";
	flags.zero					();
}
Example #8
0
	virtual void Execute(LPCSTR arguments)
	{
		if (!arguments || !*arguments) {
			Msg					("! no arguments passed");
			return;
		}

		string_path				name;
		string_path				fn;

		if (0==strext(arguments))
			strconcat			(sizeof(name),name,arguments,".ogf");
		else
			strcpy_s			(name,sizeof(name),arguments);

		if (!FS.exist(arguments) && !FS.exist(fn, "$level$", name) && !FS.exist(fn, "$game_meshes$", name)) {
			Msg					("! Cannot find visual \"%s\"",arguments);
			return;
		}

		IRender_Visual			*visual = Render->model_Create(arguments);
		CKinematics				*kinematics = smart_cast<CKinematics*>(visual);
		if (!kinematics) {
			Render->model_Delete(visual);
			Msg					("! Invalid visual type \"%s\" (not a CKinematics)",arguments);
			return;
		}

		Msg						("bones for model \"%s\"",arguments);
		for (u16 i=0, n=kinematics->LL_BoneCount(); i<n; ++i)
			Msg					("%s",*kinematics->LL_GetData(i).name);
		
		Render->model_Delete	(visual);
	}
Example #9
0
void CObjectAnimator::LoadMotions(LPCSTR fname)
{
	string_path			full_path;
	if (!FS.exist( full_path, "$level$", fname ))
		if (!FS.exist( full_path, "$game_anims$", fname ))
			Debug.fatal(DEBUG_INFO,"Can't find motion file '%s'.",fname);
            
    LPCSTR  ext			= strext(full_path);
    if (ext){
		Clear			();
    	if (0==xr_strcmp(ext,".anm")){
            COMotion* M	= xr_new<COMotion> ();
            if (M->LoadMotion(full_path)) m_Motions.push_back(M);
            else				FATAL("ERROR: Can't load motion. Incorrect file version.");
        }else if (0==xr_strcmp(ext,".anms")){
            IReader* F			= FS.r_open(full_path);
            u32 dwMCnt			= F->r_u32(); VERIFY(dwMCnt);
            for (u32 i=0; i<dwMCnt; i++){
                COMotion* M		= xr_new<COMotion> ();
                bool bRes		= M->Load(*F);
                if (!bRes)		FATAL("ERROR: Can't load motion. Incorrect file version.");
                m_Motions.push_back(M);
            }
            FS.r_close		(F);
        }
        std::sort(m_Motions.begin(),m_Motions.end(),motion_sort_pred);
    }
}
Example #10
0
CDemoPlay::CDemoPlay(const char *name, float ms, u32 cycles, float life_time) : CEffectorCam(cefDemo,life_time/*,FALSE*/)
{
	Msg					("*** Playing demo: %s",name);
	Console->Execute	("hud_weapon 0");
	if(g_bBenchmark)	Console->Execute	("hud_draw 0");

	fSpeed				= ms;
	dwCyclesLeft		= cycles?cycles:1;

	m_pMotion			= 0;
	m_MParam			= 0;
	string_path			nm, fn;
	strcpy_s			(nm,sizeof(nm),name);	
	
	if (strext(nm))	
		strcpy(strext(nm),".anm");

	if ( FS.exist(fn,"$level$",nm) || FS.exist(fn,"$game_anims$",nm) )
	{
		m_pMotion				= xr_new<COMotion>		();
		m_pMotion->LoadMotion	(fn);
		m_MParam				= xr_new<SAnimParams>	();
		m_MParam->Set			(m_pMotion);
		m_MParam->Play			();
	}else{
		if (!FS.exist(name))						{
			g_pGameLevel->Cameras().RemoveCamEffector	(cefDemo);
			return		;
		}
		IReader*	fs	= FS.r_open	(name);
		u32 sz			= fs->length();
		if				(sz%sizeof(Fmatrix) != 0)	{
			FS.r_close	(fs);
			g_pGameLevel->Cameras().RemoveCamEffector	(cefDemo);
			return		;
		}
		
		seq.resize		(sz/sizeof(Fmatrix));
		m_count			= seq.size();
		CopyMemory	(&*seq.begin(),fs->pointer(),sz);
		FS.r_close		(fs);
		Log				("~ Total key-frames: ",m_count);
	}
	stat_started		= FALSE;
	Device.PreCache		(50);
}
Example #11
0
void FHierrarhyVisual::Load(const char* N, IReader *data, u32 dwFlags)
{
	dxRender_Visual::Load(N,data,dwFlags);
	if (data->find_chunk(OGF_CHILDREN_L)) 
	{
		// From Link
		u32 cnt = data->r_u32		();
		children.resize				(cnt);
		for (u32 i=0; i<cnt; i++)	{
#ifdef _EDITOR
			THROW;
#else
			u32 ID	= data->r_u32();
			children[i]	= (dxRender_Visual*)::Render->getVisual(ID);
#endif
		}
		bDontDelete = TRUE;
	}
	else
	{	
    	if (data->find_chunk(OGF_CHILDREN))
		{
			// From stream
            IReader* OBJ = data->open_chunk(OGF_CHILDREN);
            if (OBJ){
                IReader* O = OBJ->open_chunk(0);
                for (int count=1; O; count++) {
					string_path			name_load,short_name,num;
					xr_strcpy				(short_name,N);
					if (strext(short_name)) *strext(short_name)=0;
					strconcat			(sizeof(name_load),name_load,short_name,":",itoa(count,num,10));
					children.push_back	((dxRender_Visual*)::Render->model_CreateChild(name_load,O));
                    O->close			();
                    O = OBJ->open_chunk	(count);
                }
                OBJ->close();
            }
			bDontDelete = FALSE;
        }
		else
		{
			FATAL		("Invalid visual");
    	}
	}
}
Example #12
0
dxRender_Visual* CModelPool::CreateChild(LPCSTR name, IReader* data)
{
	string256 low_name;		VERIFY	(xr_strlen(name)<256);
	strcpy_s(low_name,name);	strlwr	(low_name);
	if (strext(low_name))	*strext	(low_name) = 0;

	// 1. Search for already loaded model
	dxRender_Visual* Base	= Instance_Find(low_name);
//.	if (0==Base) Base	 	= Instance_Load(name,data,FALSE);
	if(0==Base)
	{
		if (data)		Base = Instance_Load	(low_name,data,FALSE);
		else			Base = Instance_Load	(low_name,FALSE);
	}

    dxRender_Visual* Model	= bAllowChildrenDuplicate?Instance_Duplicate(Base):Base;
    return					Model;
}
Example #13
0
//-----------------------------------------------------------------------------------------
BOOL CEditableObject::ParseMAMaterial(CSurface* dest, SXRShaderData& d)
{
	string1024 tmp;
	strcpy				(tmp,d.tex_name.asChar());	if (strext(tmp)) *strext(tmp)=0;
	dest->SetTexture	(EFS.AppendFolderToName(tmp,1,TRUE));
	dest->SetFVF		(D3DFVF_XYZ|D3DFVF_NORMAL|(1<<D3DFVF_TEXCOUNT_SHIFT));
	dest->SetVMap		("Texture");
	dest->m_Flags.set	(CSurface::sf2Sided,d.double_side);
	LPCSTR sh_name		= _ChangeSymbol(strcpy(tmp,d.eng_name.asChar()),'/','\\');
	if (!sh_name||!sh_name[0]){
		Log("! Empty shader name, material: ",d.name.asChar());
		return FALSE;
	}
	dest->SetShader		(sh_name);
	dest->SetShaderXRLC	(_ChangeSymbol(strcpy(tmp,d.comp_name.asChar()),'/','\\'));
	dest->SetGameMtl	(_ChangeSymbol(strcpy(tmp,d.gmat_name.asChar()),'/','\\'));
	return TRUE;
}
Example #14
0
void fix_texture_name(LPSTR fn)
{
	LPSTR _ext = strext(fn);
	if(  _ext					&&
	  (0==stricmp(_ext,".tga")	||
		0==stricmp(_ext,".dds")	||
		0==stricmp(_ext,".bmp")	||
		0==stricmp(_ext,".ogm")	) )
		*_ext = 0;
}
Example #15
0
void CObject::Load				(LPCSTR section )
{
	// Name
	R_ASSERT					(section);
	cName_set					(section);
	cNameSect_set				(section);
	
	// Visual and light-track
	if (pSettings->line_exist(section,"visual")){
		string_path					tmp;
		strcpy					(tmp, pSettings->r_string(section,"visual"));
		if(strext(tmp)) 
			*strext(tmp)			=0;
		xr_strlwr					(tmp);

		cNameVisual_set				(tmp);
	}
	setVisible					(false);
}
void EFS_Utils::MarkFile(LPCSTR fn, bool bDeleteSource)
{
	xr_string ext = strext(fn);
	ext.insert		(1,"~");
	xr_string backup_fn = EFS.ChangeFileExt(fn,ext.c_str());
	if (bDeleteSource){
		FS.file_rename(fn,backup_fn.c_str(),true);
	}else{
		FS.file_copy(fn,backup_fn.c_str());
	}
}
Example #17
0
void CPartition::load(IKinematics* V, LPCSTR model_name)
{
	string_path fn, fn_full;
	strcpy_s(fn, sizeof(fn), model_name);
	if(strext(fn))
		*strext(fn) = 0;
	strcat_s(fn, sizeof(fn), ".ltx");
	
	FS.update_path(fn_full,"$game_meshes$", fn);

	CInifile ini(fn_full, TRUE, TRUE, FALSE);

	if(ini.sections().size()==0)	return;
	shared_str part_name = "partition_name";
	for(u32 i=0; i<MAX_PARTS; ++i)
	{
		string64			buff;
		sprintf_s			(buff,sizeof(buff), "part_%d", i);
		
		CInifile::Sect S		= ini.r_section(buff);
		CInifile::SectCIt it	= S.Data.begin();
		CInifile::SectCIt it_e	= S.Data.end();
		if(S.Data.size())
		{
			P[i].bones.clear_not_free();
		}
		for(;it!=it_e; ++it)
		{
			const CInifile::Item& I = *it;
			if(I.first==part_name)
			{
				P[i].Name = I.second;
			}else
			{
				u32 bid = V->LL_BoneID(I.first.c_str());
				P[i].bones.push_back(bid);
			}
		}
		
	}
}
Example #18
0
dxRender_Visual* CModelPool::Create(const char* name, IReader* data)
{
#ifdef _EDITOR
	if (!name||!name[0])	return 0;
#endif
	string_path low_name;	VERIFY	(xr_strlen(name)<sizeof(low_name));
	strcpy_s(low_name,name);	strlwr	(low_name);
	if (strext(low_name))	*strext	(low_name)=0;
//	Msg						("-CREATE %s",low_name);

	// 0. Search POOL
	POOL_IT	it			=	Pool.find	(low_name);
	if (it!=Pool.end())
	{
		// 1. Instance found
        dxRender_Visual*		Model	= it->second;
		Model->Spawn		();
		Pool.erase			(it);
		return				Model;
	} else {
		// 1. Search for already loaded model (reference, base model)
		dxRender_Visual* Base		= Instance_Find		(low_name);

		if (0==Base){
			// 2. If not found
			bAllowChildrenDuplicate	= FALSE;
			if (data)		Base = Instance_Load(low_name,data,TRUE);
            else			Base = Instance_Load(low_name,TRUE);
			bAllowChildrenDuplicate	= TRUE;
#ifdef _EDITOR
			if (!Base)		return 0;
#endif
		}
        // 3. If found - return (cloned) reference
        dxRender_Visual*		Model	= Instance_Duplicate(Base);
        Registry.insert		( mk_pair(Model,low_name) );
        return				Model;
	}
}
Example #19
0
void CCC_LoadCFG::Execute(LPCSTR args)
{
    Msg("Executing config-script \"%s\"...", args);
    string_path cfg_name;

    xr_strcpy(cfg_name, args);
    if (strext(cfg_name)) *strext(cfg_name) = 0;
    xr_strcat(cfg_name, ".ltx");

    string_path cfg_full_name;

    FS.update_path(cfg_full_name, "$app_data_root$", cfg_name);

    if (NULL == FS.exist(cfg_full_name))
        FS.update_path(cfg_full_name, "$fs_root$", cfg_name);

    if (NULL == FS.exist(cfg_full_name))
        xr_strcpy(cfg_full_name, cfg_name);

    IReader* F = FS.r_open(cfg_full_name);

    string1024 str;
    if (F != NULL)
    {
        while (!F->eof())
        {
            F->r_string(str, sizeof(str));
            if (allow(str))
                Console->Execute(str);
        }
        FS.r_close(F);
        Msg("[%s] successfully loaded.", cfg_full_name);
    }
    else
    {
        Msg("! Cannot open script file [%s]", cfg_full_name);
    }
}
Example #20
0
BOOL MeshExpUtility::SaveAsObject(const char* m_ExportName)
{
	BOOL bResult = TRUE;

	if (m_ExportName[0]==0) return FALSE;

	ELog.Msg(mtInformation,"Exporting..." );
	ELog.Msg(mtInformation,"-------------------------------------------------------" );
	CEditableObject* exp_obj=0;	
	if (bResult=BuildObject(exp_obj,m_ExportName)){
		ELog.Msg				(mtInformation,"Saving object...");
		for (SurfaceIt s_it=exp_obj->FirstSurface(); s_it!=exp_obj->LastSurface(); s_it++){
			LPSTR t=(LPSTR)(*s_it)->_Texture();
			if (strext(t)) *strext(t)=0;
		}
		exp_obj->Optimize		();
		exp_obj->SaveObject		(m_ExportName);
	}

	xr_delete(exp_obj);

	return bResult;
}
Example #21
0
/* -- open the output file -- */
void open_fout(void)
{
	int i;
	char fnm[FILENAME_MAX];

	strcpy(fnm, outfn);
	i = strlen(fnm) - 1;
	if (i < 0) {
		strcpy(fnm, svg || epsf > 1 ? "Out.xhtml" : OUTPUTFILE);
	} else if (i != 0 || fnm[0] != '-') {
		if (fnm[i] == '=' && in_fname) {
			char *p;

			if ((p = strrchr(in_fname, DIRSEP)) == NULL)
				p = in_fname;
			else
				p++;
			strcpy(&fnm[i], p);
			strext(fnm, svg || epsf > 1 ? "xhtml" : "ps");
		} else if (fnm[i] == DIRSEP) {
			strcpy(&fnm[i + 1],
				svg || epsf > 1 ? "Out.xhtml" : OUTPUTFILE);
		}
#if 0
/*fixme: fnm may be a directory*/
		else	...
#endif
	}
	if (svg == 1
	 && (i != 0 || fnm[0] != '-')) {
		cutext(fnm);
		i = strlen(fnm) - 1;
		if (strncmp(fnm, outfnam, i) != 0)
			nepsf = 0;
		sprintf(&fnm[i + 1], "%03d.svg", ++nepsf);
	} else if (strcmp(fnm, outfnam) == 0) {
		return;				/* same output file */
	}

	close_output_file();
	strcpy(outfnam, fnm);
	if (i != 0 || fnm[0] != '-') {
		if ((fout = fopen(fnm, "w")) == NULL) {
			error(1, NULL, "Cannot create output file %s - abort", fnm);
			exit(EXIT_FAILURE);
		}
	} else {
		fout = stdout;
	}
}
void CSoundRender_Source::load(LPCSTR name)
{
	string_path			fn,N;
	strcpy				(N,name);
	strlwr				(N);
	if (strext(N))		*strext(N) = 0;

	fname				= N;

	strconcat			(sizeof(fn),fn,N,".ogg");
	if (!FS.exist("$level$",fn))	FS.update_path	(fn,"$game_sounds$",fn);

#ifdef _EDITOR
	if (!FS.exist(fn)){ 
		FS.update_path	(fn,"$game_sounds$","$no_sound.ogg");
    }
#endif
	LoadWave			(fn);		//.R_ASSERT(wave);
	SoundRender->cache.cat_create	(CAT, dwBytesTotal);

//	if (dwTimeTotal<100)					{
//		Msg	("! WARNING: Invalid wave length (must be at least 100ms), file: %s",fn);
//	}
}
Example #23
0
xr_string EFS_Utils::ChangeFileExt(LPCSTR src, LPCSTR ext)
{
    xr_string tmp;
    LPSTR src_ext = strext(src);
    if (src_ext)
    {
        size_t ext_pos = src_ext - src;
        tmp.assign(src, 0, ext_pos);
    }
    else
    {
        tmp = src;
    }
    tmp += ext;
    return tmp;
}
Example #24
0
dxRender_Visual*	CModelPool::Instance_Load		(const char* N, BOOL allow_register)
{
	dxRender_Visual	*V;
	string_path		fn;
	string_path		name;

	// Add default ext if no ext at all
	if (0==strext(N))	strconcat	(sizeof(name),name,N,".ogf");
	else				strcpy_s	(name,sizeof(name),N);

	// Load data from MESHES or LEVEL
	if (!FS.exist(N))	{
		if (!FS.exist(fn, "$level$", name))
			if (!FS.exist(fn, "$game_meshes$", name)){
#ifdef _EDITOR
				Msg("! Can't find model file '%s'.",name);
                return 0;
#else            
				xrDebug::Fatal(DEBUG_INFO,"Can't find model file '%s'.",name);
#endif
			}
	} else {
		strcpy_s			(fn,N);
	}
	
	// Actual loading
#ifdef DEBUG
	if (bLogging)		Msg		("- Uncached model loading: %s",fn);
#endif // DEBUG

	IReader*			data	= FS.r_open(fn);
	ogf_header			H;
	data->r_chunk_safe	(OGF_HEADER,&H,sizeof(H));
	V = Instance_Create (H.type);
	V->Load				(N,data,0);
	FS.r_close			(data);
	g_pGamePersistent->RegisterModel(V);

	// Registration
	if (allow_register) Instance_Register(N,V);

	return V;
}
Example #25
0
void CGameFont::Initialize		(LPCSTR cShader, LPCSTR cTextureName)
{
	string_path					cTexture;

	LPCSTR _lang				= pSettings->r_string("string_table", "font_prefix");
	bool is_di					= strstr(cTextureName, "ui_font_hud_01") || 
								  strstr(cTextureName, "ui_font_hud_02") ||
								  strstr(cTextureName, "ui_font_console_02");
	if(_lang && !is_di)
		strconcat				(sizeof(cTexture),cTexture, cTextureName, _lang);
	else
		strcpy_s				(cTexture, sizeof(cTexture), cTextureName);

	uFlags						&=~fsValid;
	vTS.set						(1.f,1.f); // обязательно !!!

	eCurrentAlignment			= alLeft;
	vInterval.set				(1.f,1.f);

	strings.reserve				(128);

	// check ini exist
	string_path fn,buf;
	strcpy_s		(buf,cTexture); if (strext(buf)) *strext(buf)=0;
	R_ASSERT2	(FS.exist(fn,"$game_textures$",buf,".ini"),fn);
	CInifile* ini				= CInifile::Create(fn);

	nNumChars = 0x100;
	TCMap = ( Fvector* ) xr_realloc( ( void* ) TCMap , nNumChars * sizeof( Fvector ) );

	if ( ini->section_exist( "mb_symbol_coords" ) ) {
		nNumChars = 0x10000;
		TCMap = ( Fvector* ) xr_realloc( ( void* ) TCMap , nNumChars * sizeof( Fvector ) );
		uFlags |= fsMultibyte;
		fHeight = ini->r_float( "mb_symbol_coords" , "height" );
		
		fXStep = ceil( fHeight / 2.0f );

		// Searching for the first valid character

		Fvector vFirstValid = {0,0,0};

		if ( ini->line_exist( "mb_symbol_coords" , "09608" ) ) {
			Fvector v = ini->r_fvector3( "mb_symbol_coords" , "09608" );
			vFirstValid.set( v.x , v.y , 1 + v[2] - v[0] );
		} else 
		for ( u32 i=0 ; i < nNumChars ; i++ ) {
			sprintf_s( buf ,sizeof(buf), "%05d" , i );
			if ( ini->line_exist( "mb_symbol_coords" , buf ) ) {
				Fvector v = ini->r_fvector3( "mb_symbol_coords" , buf );
				vFirstValid.set( v.x , v.y , 1 + v[2] - v[0] );
				break;
			}
		}

		// Filling entire character table

		for ( u32 i=0 ; i < nNumChars ; i++ ) {
			sprintf_s( buf ,sizeof(buf), "%05d" , i );
			if ( ini->line_exist( "mb_symbol_coords" , buf ) ) {
				Fvector v = ini->r_fvector3( "mb_symbol_coords" , buf );
				TCMap[i].set( v.x , v.y , 1 + v[2] - v[0] );
			} else
				TCMap[i] = vFirstValid; // "unassigned" unprintable characters
		}

		// Special case for space
		TCMap[ 0x0020 ].set( 0 , 0 , 0 );
		// Special case for ideographic space
		TCMap[ 0x3000 ].set( 0 , 0 , 0 );


	}else
	if (ini->section_exist("symbol_coords"))
	{
		float d						= 0.0f;
//.		if(ini->section_exist("width_correction"))
//.			d						= ini->r_float("width_correction", "value");

		fHeight						= ini->r_float("symbol_coords","height");
		for (u32 i=0; i<nNumChars; i++){
			sprintf_s				(buf,sizeof(buf),"%03d",i);
			Fvector v				= ini->r_fvector3("symbol_coords",buf);
			TCMap[i].set			(v.x,v.y,v[2]-v[0]+d);
		}
	}else{
	if (ini->section_exist("char widths")){
		fHeight					= ini->r_float("char widths","height");
		int cpl					= 16;
		for (u32 i=0; i<nNumChars; i++){
			sprintf_s			(buf,sizeof(buf),"%d",i);
			float w				= ini->r_float("char widths",buf);
			TCMap[i].set		((i%cpl)*fHeight,(i/cpl)*fHeight,w);
		}
	}else{
		R_ASSERT(ini->section_exist("font_size"));
		fHeight					= ini->r_float("font_size","height");
		float width				= ini->r_float("font_size","width");
		const int cpl			= ini->r_s32	("font_size","cpl");
		for (u32 i=0; i<nNumChars; i++)
			TCMap[i].set		((i%cpl)*width,(i/cpl)*fHeight,width);
		}
	}

	fCurrentHeight				= fHeight;

	CInifile::Destroy			(ini);

	// Shading
	pFontRender->Initialize(cShader, cTexture);
}
Example #26
0
File: words.c Project: jnbek/TekNap
/*
 * extract2 is the word extractor that is used when its important to us
 * that 'firstword' get special treatment if it is negative (specifically,
 * that it refer to the "firstword"th word from the END).  This is used
 * basically by the ${n}{-m} expandos and by function_rightw(). 
 *
 * Note that because of a lot of flak, if you do an expando that is
 * a "range" of words, unless you #define STRIP_EXTRANEOUS_SPACES,
 * the "n"th word will be backed up to the first character after the
 * first space after the "n-1"th word.  That apparantly is what everyone
 * wants, so thats whatll be the default.  Those of us who may not like
 * that behavior or are at ambivelent can just #define it.
 */
char *	real_extract2 (const char *start, int firstword, int lastword, int extended)
{
	/* 
	 * If firstword or lastword is negative, then
	 * we take those values from the end of the string
	 */
	const char *	mark;
	const char *	mark2;
	char *		booya = NULL;

	CHECK_EXTENDED_SUPPORT
	/* If firstword is EOS, then the user wants the last word */
	if (firstword == EOS)
	{
		mark = start + strlen(start);
		mark = move_word_rel(start, &mark, -1, extended);
#ifndef NO_CHEATING
		/* 
		 * Really. the only case where firstword == EOS is
		 * when the user wants $~, in which case we really
		 * dont need to do all the following crud.  Of
		 * course, if there ever comes a time that the
		 * user would want to start from the EOS (when?)
		 * we couldnt make this assumption.
		 */
		return m_strdup(mark);
#endif
	}

	/* 
	 * SOS is used when the user does $-n, all leading spaces 
	 * are retained  
	 */
	else if (firstword == SOS)
		mark = start;

	/* If the firstword is positive, move to that word */
	/* Special treatment for $X-, where X is out of range
	 * added by Colten Edwards, fixes the $1- bug.. */
	else if (firstword >= 0)
	{
		real_move_to_abs_word(start, &mark, firstword, extended);
		if (!*mark)
			return m_strdup(empty_string);
	}

	/* Otherwise, move to the firstwords from the end */
	else
	{
		mark = start + strlen(start);
		move_word_rel(start, &mark, firstword, extended);
	}

#ifndef STRIP_EXTRANEOUS_SPACES
	/* IF the user did something like this:
	 *	$n-  $n-m
	 * then include any leading spaces on the 'n'th word.
	 * this is the "old" behavior that we are attempting
	 * to emulate here.
	 */
#ifndef NO_CHEATING
	if (lastword == EOS || (lastword > firstword))
#else
	if (((lastword == EOS) && (firstword != EOS)) || (lastword > firstword))
#endif
	{
		while (mark > start && my_isspace(mark[-1]))
			mark--;
		if (mark > start)
			mark++;
	}
#endif

	/* 
	 * When we find the last word, we need to move to the 
         * END of the word, so that word 3 to 3, would include
	 * all of word 3, so we sindex to the space after the word
	 */
	if (lastword == EOS)
		mark2 = mark + strlen(mark);

	else 
	{
		if (lastword >= 0)
			real_move_to_abs_word(start, &mark2, lastword+1, extended);
		else
		{
			mark2 = start + strlen(start);
			move_word_rel(start, &mark2, lastword, extended);
		}

		while (mark2 > start && my_isspace(mark2[-1]))
			mark2--;
	}

	/* 
	 * If the end is before the string, then there is nothing
	 * to extract (this is perfectly legal, btw)
         */
	if (mark2 < mark)
		booya = m_strdup(empty_string);

	else
	{
		/*
		 * This is kind of tricky, because the string we are
		 * copying out of is const.  So we cant just null off
		 * the trailing character and m_strdup it.
		 */
		booya = strext(mark, mark2);
	}

	return booya;
}
Example #27
0
File: words.c Project: jnbek/TekNap
/*
 * extract is a simpler version of extract2, it is used when we dont
 * want special treatment of "firstword" if it is negative.  This is
 * typically used by the word/list functions, which also dont care if
 * we strip out or leave in any whitespace, we just do what is the
 * fastest.
 */
char *	real_extract (char *start, int firstword, int lastword, int extended)
{
	/* 
	 * firstword and lastword must be zero.  If they are not,
	 * then they are assumed to be invalid  However, please note
	 * that taking word set (-1,3) is valid and contains the
	 * words 0, 1, 2, 3.  But word set (-1, -1) is an empty_string.
	 */
	char *	mark;
	char *	mark2;
	char *	booya = NULL;

	CHECK_EXTENDED_SUPPORT
	/* 
	 * Before we do anything, we strip off leading and trailing
	 * spaces. 
	 *
	 * ITS OK TO TAKE OUT SPACES HERE, AS THE USER SHOULDNT EXPECT
	 * THAT THE WORD FUNCTIONS WOULD RETAIN ANY SPACES. (That is
	 * to say that since the word/list functions dont pay attention
	 * to the whitespace anyhow, noone should have any problem with
	 * those ops removing bothersome whitespace when needed.)
	 */
	while (my_isspace(*start))
		start++;
	remove_trailing_spaces(start);

	if (firstword == EOS)
	{
		mark = start + strlen(start);
		mark = (char *)move_word_rel(start, (const char **)&mark, -1, extended);
	}

	/* If the firstword is positive, move to that word */
	else if (firstword >= 0)
		real_move_to_abs_word(start, (const char **)&mark, firstword, extended);

	/* Its negative.  Hold off right now. */
	else
		mark = start;


	/* 
	 * When we find the last word, we need to move to the 
         * END of the word, so that word 3 to 3, would include
	 * all of word 3, so we sindex to the space after the word
 	 */
	/* EOS is a #define meaning "end of string" */
	if (lastword == EOS)
		mark2 = start + strlen(start);
	else 
	{
		if (lastword >= 0)
			real_move_to_abs_word(start, (const char **)&mark2, lastword+1, extended);
		else
			/* its negative -- thats not valid */
			return m_strdup(empty_string);

		while (mark2 > start && my_isspace(mark2[-1]))
			mark2--;
	}

	/*
	 * Ok.. now if we get to here, then lastword is positive, so
	 * we sanity check firstword.
	 */
	if (firstword < 0)
		firstword = 0;
	if (firstword > lastword)	/* this works even if fw was < 0 */
		return m_strdup(empty_string);

	/* 
	 * If the end is before the string, then there is nothing
	 * to extract (this is perfectly legal, btw)
         */
	if (mark2 < mark)
		return m_strdup(empty_string);

	booya = strext(mark, mark2);
	return booya;
}
Example #28
0
void	CKinematics::Load(const char* N, IReader *data, u32 dwFlags)
{
	//Msg				("skeleton: %s",N);
	inherited::Load	(N, data, dwFlags);

    pUserData		= NULL;
    m_lod			= NULL;
    // loading lods

	IReader* LD 	= data->open_chunk(OGF_S_LODS);
    if (LD)
	{
        string_path		short_name;
        strcpy_s		(short_name,sizeof(short_name),N);

        if (strext(short_name)) *strext(short_name)=0;
        // From stream
		{
			string_path		lod_name;
			LD->r_string	(lod_name, sizeof(lod_name));
//.         strconcat		(sizeof(name_load),name_load, short_name, ":lod:", lod_name.c_str());
            m_lod 			= ::Render->model_CreateChild(lod_name, NULL);
            VERIFY3(m_lod,"Cant create LOD model for", N);
//.			VERIFY2			(m_lod->Type==MT_HIERRARHY || m_lod->Type==MT_PROGRESSIVE || m_lod->Type==MT_NORMAL,lod_name.c_str());
/*
			strconcat		(name_load, short_name, ":lod:1");
            m_lod 			= ::Render->model_CreateChild(name_load,LD);
			VERIFY			(m_lod->Type==MT_SKELETON_GEOMDEF_PM || m_lod->Type==MT_SKELETON_GEOMDEF_ST);
*/
        }
        LD->close	();
    }

#ifndef _EDITOR    
	// User data
	IReader* UD 	= data->open_chunk(OGF_S_USERDATA);
    pUserData		= UD?xr_new<CInifile>(UD,FS.get_path("$game_config$")->m_Path):0;
    if (UD)			UD->close();
#endif

	// Globals
	bone_map_N		= xr_new<accel>		();
	bone_map_P		= xr_new<accel>		();
	bones			= xr_new<vecBones>	();
	bone_instances	= NULL;

	// Load bones
#pragma todo("container is created in stack!")
	xr_vector<shared_str>	L_parents;

	R_ASSERT		(data->find_chunk(OGF_S_BONE_NAMES));

    visimask.zero	();
	int dwCount 	= data->r_u32();
	// Msg				("!!! %d bones",dwCount);
	// if (dwCount >= 64)	Msg			("!!! More than 64 bones is a crazy thing! (%d), %s",dwCount,N);
	VERIFY3			(dwCount < 64, "More than 64 bones is a crazy thing!",N);
	for (; dwCount; dwCount--)		{
		string256	buf;

		// Bone
		u16			ID				= u16(bones->size());
		data->r_stringZ				(buf,sizeof(buf));	strlwr(buf);
		CBoneData* pBone 			= CreateBoneData(ID);
		pBone->name					= shared_str(buf);
		pBone->child_faces.resize	(children.size());
		bones->push_back			(pBone);
		bone_map_N->push_back		(mk_pair(pBone->name,ID));
		bone_map_P->push_back		(mk_pair(pBone->name,ID));

		// It's parent
		data->r_stringZ				(buf,sizeof(buf));	strlwr(buf);
		L_parents.push_back			(buf);

		data->r						(&pBone->obb,sizeof(Fobb));
        visimask.set				(u64(1)<<ID,TRUE);
	}
	std::sort	(bone_map_N->begin(),bone_map_N->end(),pred_sort_N);
	std::sort	(bone_map_P->begin(),bone_map_P->end(),pred_sort_P);

	// Attach bones to their parents
	iRoot = BI_NONE;
	for (u32 i=0; i<bones->size(); i++) {
		shared_str	P 		= L_parents[i];
		CBoneData* B	= (*bones)[i];
		if (!P||!P[0]) {
			// no parent - this is root bone
			R_ASSERT	(BI_NONE==iRoot);
			iRoot		= u16(i);
			B->SetParentID(BI_NONE);
			continue;
		} else {
			u16 ID		= LL_BoneID(P);
			R_ASSERT	(ID!=BI_NONE);
			(*bones)[ID]->children.push_back(B);
			B->SetParentID(ID);
		}
	}
	R_ASSERT	(BI_NONE != iRoot);

	// Free parents
    L_parents.clear();

    // IK data
	IReader* IKD 	= data->open_chunk(OGF_S_IKDATA);
    if (IKD){
        for (u32 i=0; i<bones->size(); i++) {
            CBoneData*	B 	= (*bones)[i];
            u16 vers		= (u16)IKD->r_u32();
            IKD->r_stringZ	(B->game_mtl_name);
            IKD->r			(&B->shape,sizeof(SBoneShape));
            B->IK_data.Import(*IKD,vers);
            Fvector vXYZ,vT;
            IKD->r_fvector3	(vXYZ);
            IKD->r_fvector3	(vT);
            B->bind_transform.setXYZi(vXYZ);
            B->bind_transform.translate_over(vT);
	        B->mass			= IKD->r_float();
    	    IKD->r_fvector3	(B->center_of_mass);
        }
        // calculate model to bone converting matrix
        (*bones)[LL_GetBoneRoot()]->CalculateM2B(Fidentity);
    	IKD->close();
    }

	// after load process
	{
		for (u16 child_idx=0; child_idx<(u16)children.size(); child_idx++)
			LL_GetChild(child_idx)->AfterLoad	(this,child_idx);
	}

	// unique bone faces
	{
		for (u32 bone_idx=0; bone_idx<bones->size(); bone_idx++) {
			CBoneData*	B 	= (*bones)[bone_idx];
			for (u32 child_idx=0; child_idx<children.size(); child_idx++){
				CBoneData::FacesVec faces		= B->child_faces[child_idx];
				std::sort						(faces.begin(),faces.end());
				CBoneData::FacesVecIt new_end	= std::unique(faces.begin(),faces.end());
				faces.erase						(new_end,faces.end());
				B->child_faces[child_idx].clear_and_free();
				B->child_faces[child_idx]		= faces;
			}
		}
	}

	// reset update_callback
	Update_Callback	= NULL;
	// reset update frame
	wm_frame		= u32(-1);

    LL_Validate		();
}
Example #29
0
/*
bool CEditableObject::LoadSMotions(const char* fname)
{
	IReader* F	= FS.r_open(fname);
    ClearSMotions();
    // object motions
    m_SMotions.resize(F->r_u32());
	SetActiveSMotion(0);
    for (SMotionIt m_it=m_SMotions.begin(); m_it!=m_SMotions.end(); m_it++){
        *m_it = xr_new<CSMotion>();
        if (!(*m_it)->Load(*F)){
            ELog.DlgMsg(mtError,"Motions has different version. Load failed.");
            xr_delete(*m_it);
            m_SMotions.clear();
            FS.r_close(F);
            return false;
        }
	  	if (!CheckBoneCompliance(*m_it)){
        	ClearSMotions();
            ELog.DlgMsg(mtError,"Load failed.",fname);
            xr_delete(&*m_it);
            FS.r_close(F);
            return false;
        }
    }
	FS.r_close(F);
	return true;
}
*/
bool CEditableObject::AppendSMotion(LPCSTR fname, SMotionVec* inserted)
{
	VERIFY(IsSkeleton());

    bool bRes	= true;
    
	LPCSTR ext	= strext(fname);
    if (0==stricmp(ext,".skl")){
        CSMotion* M = xr_new<CSMotion>();
        if (!M->LoadMotion(fname)){
            ELog.Msg(mtError,"Motion '%s' can't load. Append failed.",fname);
            xr_delete(M);
            bRes = false;
        }else{
        	string256 name;
			_splitpath(fname,0,0,name,0);
            if (CheckBoneCompliance(M)){
                M->SortBonesBySkeleton(m_Bones);
                string256 			m_name;
                GenerateSMotionName	(m_name,name,M);
                M->SetName			(m_name);
                m_SMotions.push_back(M);
                if (inserted)		inserted->push_back(M);
                // optimize
                M->Optimize			();
            }else{
                ELog.Msg(mtError,"Append failed.",fname);
                xr_delete(M);
	            bRes = false;
            }
        }
    }else if (0==stricmp(ext,".skls")){
        IReader* F	= FS.r_open(fname);
        if (!F){ 
        	ELog.Msg(mtError,"Can't open file '%s'.",fname);
            bRes = false;
    	}
        if (bRes){
            // object motions
            int cnt 	= F->r_u32();
            for (int k=0; k<cnt; k++){
                CSMotion* M	= xr_new<CSMotion>();
                if (!M->Load(*F)){
                    ELog.Msg(mtError,"Motion '%s' has different version. Load failed.",M->Name());
                    xr_delete(M);
                    bRes = false;
                    break;
                }
                if (!CheckBoneCompliance(M)){
                    xr_delete(M);
                    bRes = false;
                    break;
                }
                if (bRes){
                    M->SortBonesBySkeleton(m_Bones);
                    string256 			m_name;
                    GenerateSMotionName	(m_name,M->Name(),M);
                    M->SetName			(m_name);
                    m_SMotions.push_back(M);
                    if (inserted)		inserted->push_back(M);
                    // optimize
                    M->Optimize			();
                }
            }
        }
        FS.r_close(F);
    }
    return bRes;
}
Example #30
0
bool CEditableObject::Import_LWO(const char* fn, bool bNeedOptimize)
{
	lwObject *I=0;
//	UI->SetStatus("Importing...");
//	UI->ProgressStart(100,"Read file:");
//	UI->ProgressUpdate(1);
    string512 fname;
    strcpy(fname,fn);
#ifdef _EDITOR
	I=LWO_ImportObject(fname,I);
#else
	unsigned int failID;
	int failpos;
	I = lwGetObject( fname, &failID, &failpos );
#endif
//	UI->ProgressUpdate(100);
	if (I){
        bool bResult=true;
        ELog.Msg( mtInformation, "CEditableObject: import lwo %s...", fname );

        // parse lwo object
        {
        	m_Meshes.reserve	(I->nlayers);
            m_Surfaces.reserve	(I->nsurfs);

            // surfaces
            st_lwSurface* Isf=0;
            {
                int i=0;
//                UI->ProgressStart(I->nsurfs,"Check surf:");
                for (Isf=I->surf; Isf; Isf=Isf->next){
//                    UI->ProgressUpdate(i);
                    Isf->alpha_mode=i; // перетираем для внутренних целей !!!
                    CSurface* Osf = new CSurface();
                    m_Surfaces.push_back(Osf);
                    if (Isf->name&&Isf->name[0]) Osf->SetName(Isf->name); else Osf->SetName("Default");
                    Osf->m_Flags.set(CSurface::sf2Sided,(Isf->sideflags==3)?TRUE:FALSE);
                    AnsiString en_name="default", lc_name="default", gm_name="default";
                    XRShader* sh_info = 0;
                    if (Isf->nshaders&&(stricmp(Isf->shader->name,SH_PLUGIN_NAME)==0)){
                    	sh_info 	= (XRShader*)Isf->shader->data;
                        en_name 	= sh_info->en_name;
                        lc_name 	= sh_info->lc_name;
                        gm_name		= sh_info->gm_name;
                    }else
						ELog.Msg(mtError,"CEditableObject: Shader not found on surface '%s'.",Osf->_Name());
#ifdef _EDITOR
					if (!Device.Resources->_FindBlender(en_name.c_str())){
						ELog.Msg(mtError,"CEditableObject: Render shader '%s' - can't find in library.\nUsing 'default' shader on surface '%s'.", en_name.c_str(), Osf->_Name());
	                    en_name = "default";
					}
					if (!Device.ShaderXRLC.Get(lc_name.c_str())){
						ELog.Msg(mtError,"CEditableObject: Compiler shader '%s' - can't find in library.\nUsing 'default' shader on surface '%s'.", lc_name.c_str(), Osf->_Name());
	                    lc_name = "default";
					}
					if (!GMLib.GetMaterial(gm_name.c_str())){
						ELog.Msg(mtError,"CEditableObject: Game material '%s' - can't find in library.\nUsing 'default' material on surface '%s'.", lc_name.c_str(), Osf->_Name());
	                    gm_name = "default";
					}
#endif
                    // fill texture layers
                    int cidx;
                    st_lwClip* Icl;
                    u32 dwNumTextures=0;
                    for (st_lwTexture* Itx=Isf->color.tex; Itx; Itx=Itx->next){
                        string1024 tname="";
                        dwNumTextures++;
                        cidx = -1;
                        if (Itx->type==ID_IMAP) cidx=Itx->param.imap.cindex;
                        else{
                            ELog.DlgMsg(mtError, "Import LWO (Surface '%s'): 'Texture' is not Image Map!",Osf->_Name());
                            bResult=false;
                            break;
                        }
                        if (cidx!=-1){
                            // get textures
                            for (Icl=I->clip; Icl; Icl=Icl->next)
                                if ((cidx==Icl->index)&&(Icl->type==ID_STIL)){
                                    strcpy(tname,Icl->source.still.name);
                                    break;
                                }
                            if (tname[0]==0){
                                ELog.DlgMsg(mtError, "Import LWO (Surface '%s'): 'Texture' name is empty or non 'STIL' type!",Osf->_Name());
                                bResult=false;
                                break;
                            }
                            string256 tex_name;
                            _splitpath( tname, 0, 0, tex_name, 0 );
							Osf->SetTexture(EFS.AppendFolderToName(tex_name,1,TRUE));
                            // get vmap refs
                            Osf->SetVMap(Itx->param.imap.vmap_name);
                        }
                    }
                    if (!bResult) break;
                    if (!Osf->_VMap()||!Osf->_VMap()[0]){
						ELog.DlgMsg(mtError, "Invalid surface '%s'. VMap empty.",Osf->_Name());
                        bResult = false;
						break;
                    }
                    if (!Osf->_Texture()||!Osf->_Texture()[0]){
						ELog.DlgMsg(mtError, "Can't create shader. Invalid surface '%s'. Textures empty.",Osf->_Name());
                        bResult = false;
						break;
                    }
                    if (en_name.c_str()==0){
						ELog.DlgMsg(mtError, "Can't create shader. Invalid surface '%s'. Shader empty.",Osf->_Name());
                        bResult = false;
						break;
                    }

                    Osf->SetShader		(en_name.c_str());
					Osf->SetShaderXRLC	(lc_name.c_str());
                    Osf->SetGameMtl		(gm_name.c_str());
                    Osf->SetFVF			(D3DFVF_XYZ|D3DFVF_NORMAL|(dwNumTextures<<D3DFVF_TEXCOUNT_SHIFT));
                    i++;
                }
		    }
			if (bResult){
                // mesh layers
            	st_lwLayer* Ilr=0;
	            int k=0;
 	           	for (Ilr=I->layer; Ilr; Ilr=Ilr->next){
                    // create new mesh
                    CEditableMesh* MESH= new CEditableMesh(this);
                    m_Meshes.push_back(MESH);

                    if (Ilr->name)	MESH->SetName(Ilr->name); else MESH->SetName("");
                    MESH->m_Box.set(Ilr->bbox[0],Ilr->bbox[1],Ilr->bbox[2], Ilr->bbox[3],Ilr->bbox[4],Ilr->bbox[5]);

                    // parse mesh(lwo-layer) data
                    // vmaps
                    st_lwVMap* Ivmap=0;
                    int vmap_count=0;
                    if (Ilr->nvmaps==0){
                        ELog.DlgMsg(mtError, "Import LWO: Mesh layer must contain UV!");
                        bResult=false;
                        break;
                    }

                    // индексы соответствия импортируемых мап
					static VMIndexLink VMIndices;
				    VMIndices.clear();

                    for (Ivmap=Ilr->vmap; Ivmap; Ivmap=Ivmap->next){
                    	switch(Ivmap->type){
                        case ID_TXUV:{
                            if (Ivmap->dim!=2){
                                ELog.DlgMsg(mtError, "Import LWO: 'UV Map' must contain 2 value!");
                                bResult=false;
                                break;
                            }
                            MESH->m_VMaps.push_back(new st_VMap(Ivmap->name,vmtUV,!!Ivmap->perpoly));
                            st_VMap* Mvmap=MESH->m_VMaps.back();
                            int vcnt=Ivmap->nverts;
                            // VMap
                            Mvmap->copyfrom(*Ivmap->val,vcnt);

                            // flip uv
                            for (int k=0; k<Mvmap->size(); k++){
                            	Fvector2& uv = Mvmap->getUV(k);
                                uv.y=1.f-uv.y;
                            }
                            // vmap index
                            VMIndices[Ivmap] = vmap_count++;
                        }break;
						case ID_WGHT:{
                            if (Ivmap->dim!=1){
                                ELog.DlgMsg(mtError, "Import LWO: 'Weight' must contain 1 value!");
                                bResult=false;
                                break;
                            }
                            MESH->m_VMaps.push_back(new st_VMap(Ivmap->name,vmtWeight,false));
                            st_VMap* Mvmap=MESH->m_VMaps.back();
                            int vcnt=Ivmap->nverts;
                            // VMap
                            Mvmap->copyfrom(*Ivmap->val,vcnt);
                            // vmap index
                            VMIndices[Ivmap] = vmap_count++;
                        }break;
						case ID_PICK: ELog.Msg(mtError,"Found 'PICK' VMAP. Import failed."); bResult = false; break;
						case ID_MNVW: ELog.Msg(mtError,"Found 'MNVW' VMAP. Import failed."); bResult = false; break;
						case ID_MORF: ELog.Msg(mtError,"Found 'MORF' VMAP. Import failed."); bResult = false; break;
						case ID_SPOT: ELog.Msg(mtError,"Found 'SPOT' VMAP. Import failed."); bResult = false; break;
						case ID_RGB:  ELog.Msg(mtError,"Found 'RGB' VMAP. Import failed.");  bResult = false; break;
						case ID_RGBA: ELog.Msg(mtError,"Found 'RGBA' VMAP. Import failed."); bResult = false; break;
                        }
	                    if (!bResult) break;
                    }
                    if (!bResult) break;
                    // points
//					UI->ProgressStart(Ilr->point.count,"Fill points:");
                    {
                    	MESH->m_VertCount		= Ilr->point.count;
                        MESH->m_Vertices 		= xr_alloc<Fvector>(MESH->m_VertCount);
	                    int id 					= Ilr->polygon.count/50;

	                    if (id==0)
                        	id = 1;

                        for (int i=0; i<Ilr->point.count; ++i)
                        {
                            st_lwPoint& Ipt = Ilr->point.pt[i];
                            Fvector& Mpt	= MESH->m_Vertices[i];
                            Mpt.set			(Ipt.pos);
                        }
                    }
                    if (!bResult) break;
                    // polygons
					MESH->m_FaceCount		= Ilr->polygon.count;
                    MESH->m_Faces			= xr_alloc<st_Face>(MESH->m_FaceCount);
					MESH->m_SmoothGroups	= xr_alloc<u32>(MESH->m_FaceCount);
				    Memory.mem_fill32		(MESH->m_SmoothGroups,u32(-1),MESH->m_FaceCount);
                    MESH->m_VMRefs.reserve	(Ilr->polygon.count*3);
                    IntVec surf_ids;
                    surf_ids.resize(Ilr->polygon.count);
                    int id = Ilr->polygon.count/50;

                    if (id==0)
                    	id = 1;
                    for (int i=0; i<Ilr->polygon.count; ++i)
                    {
                        st_Face&		Mpol=MESH->m_Faces[i];
                        st_lwPolygon&   Ipol=Ilr->polygon.pol[i];
                        if (Ipol.nverts!=3) {
							ELog.DlgMsg(mtError, "Import LWO: Face must contain only 3 vertices!");
                        	bResult=false;
                            break;
                        }
                        for (int pv_i=0; pv_i<3; ++pv_i)
                        {
                        	st_lwPolVert& 	Ipv=Ipol.v[pv_i];
                            st_FaceVert&  	Mpv=Mpol.pv[pv_i];
                            Mpv.pindex		=Ipv.index;

							MESH->m_VMRefs.push_back(st_VMapPtLst());
							st_VMapPtLst&	m_vm_lst = MESH->m_VMRefs.back();

                            DEFINE_VECTOR	(st_VMapPt,VMapPtVec,VMapPtIt);
                            VMapPtVec		vm_lst;

							Mpv.vmref 		= MESH->m_VMRefs.size()-1;

							// parse uv-map
							int vmpl_cnt		=Ipv.nvmaps;
							st_lwPoint& Ipt 	=Ilr->point.pt[Mpv.pindex];
                            int vmpt_cnt		=Ipt.nvmaps;
                            if (!vmpl_cnt&&!vmpt_cnt){
                                ELog.DlgMsg	(mtError,"Found mesh without UV's!",0);
                                bResult		= false;
                                break;
                            }
                            AStringVec names;
							if (vmpl_cnt){
                            	// берем из poly
    							for (int vm_i=0; vm_i<vmpl_cnt; vm_i++){
									if (Ipv.vm[vm_i].vmap->type!=ID_TXUV) continue;
									vm_lst.push_back(st_VMapPt());
									st_VMapPt& pt	= vm_lst.back();
        							pt.vmap_index	= VMIndices[Ipv.vm[vm_i].vmap];// номер моей VMap
                                    names.push_back	(Ipv.vm[vm_i].vmap->name);
            						pt.index 		= Ipv.vm[vm_i].index;
                				}
							}
                            if (vmpt_cnt){
                            	// берем из points
                                for (int vm_i=0; vm_i<vmpt_cnt; vm_i++){
									if (Ipt.vm[vm_i].vmap->type!=ID_TXUV) continue;
                                    if (std::find(names.begin(),names.end(),Ipt.vm[vm_i].vmap->name)!=names.end()) continue;
									vm_lst.push_back(st_VMapPt());
									st_VMapPt& pt	= vm_lst.back();
									pt.vmap_index	= VMIndices[Ipt.vm[vm_i].vmap]; // номер моей VMap
									pt.index 		= Ipt.vm[vm_i].index;
                                }
							}

                            std::sort(vm_lst.begin(),vm_lst.end(),CompareFunc);

							// parse weight-map
                            int vm_cnt		=Ipt.nvmaps;
                            for (int vm_i=0; vm_i<vm_cnt; vm_i++){
								if (Ipt.vm[vm_i].vmap->type!=ID_WGHT) continue;
								vm_lst.push_back(st_VMapPt());
								st_VMapPt& pt	= vm_lst.back();
        	                    pt.vmap_index	= VMIndices[Ipt.vm[vm_i].vmap]; // номер моей VMap
            	                pt.index 		= Ipt.vm[vm_i].index;
                            }
                            m_vm_lst.count		= vm_lst.size();
                            m_vm_lst.pts		= xr_alloc<st_VMapPt>(m_vm_lst.count);
                            Memory.mem_copy		(m_vm_lst.pts,&*vm_lst.begin(),m_vm_lst.count*sizeof(st_VMapPt));
                        }
                        if (!bResult) break;
						// Ipol.surf->alpha_mode - заполнено как номер моего surface
                        surf_ids[i]			= Ipol.surf->alpha_mode;
                    }
                    if (!bResult) break;
                    for (u32 pl_id=0; pl_id<MESH->GetFCount(); pl_id++)
						MESH->m_SurfFaces[m_Surfaces[surf_ids[pl_id]]].push_back(pl_id);
                        
                    if (!bResult) break;
                    k++;
                    //MESH->DumpAdjacency();
                    if (bNeedOptimize) MESH->OptimizeMesh(false);
                    //MESH->DumpAdjacency();
                    MESH->RebuildVMaps(); // !!!!!!
                }
    		}
        }
#ifdef _EDITOR
		LWO_CloseFile(I);
#else
		lwFreeObject(I);
#endif
//		UI->ProgressEnd();
//	    UI->SetStatus("");
    	if (bResult) 	VerifyMeshNames();
        else			ELog.DlgMsg(mtError,"Can't parse LWO object.");
		if (bResult)	m_LoadName = (strext(fname))? strcpy(strext(fname),".object"):strcat(strext(fname),".object");
        return bResult;
    }else
		ELog.DlgMsg(mtError,"Can't import LWO object file.");
//	UI->ProgressEnd();
//	UI->SetStatus("");
    return false;
}