示例#1
0
void Demo::LoadAdditive()
{
	App::Data()->Add<Pool>("pool");
	App::Window()->GetRenderer().get()->Register(App::Data()->Get<Pool>("pool"));

	LoadEntities();
	LoadSystems();

	App::Log()->Info("Demo level loaded");
}
示例#2
0
bool Tutorial::Deploy()
{
    if(!LoadShaders() || !LoadEntities())
    {
        Cleanup();
        return false;
    }
    
    glClearColor(0.2, 0.2, 0.2, 1.f);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    
    return true;
}
示例#3
0
bool Tutorial::Deploy()
{
    if(!LoadShaders() || !LoadEntities())
    {
        Cleanup();
        return false;
    }
    
    glClearColor(0.2, 0.2, 0.2, 1.f);
    //enable depth test and back face culling
    glEnable(GL_DEPTH_TEST);
	glEnable(GL_CULL_FACE);

    return true;
}
示例#4
0
int SkpModel::CountAllComponents(){
	int out = 0;

	LoadEntities();
	//std::cout <<"NumEntities: " << entities_.size() << "\n";
	for (int i=0; i<entities_.size(); i++){
		out += Entities2AllComponentCount(entities_[i]);
	}

	/*
	//Get the entitites
	SUEntitiesRef entities = SU_INVALID;
  SUModelGetEntities(model_, &entities);
	
	//Count the number of all components in entitites
	out += count_all_components_entities(entities);
	*/

	/*
	//Count components in ComponentDefinitions
	size_t num_definitions = 0;
	SUModelGetNumComponentDefinitions(model_, &num_definitions);
	IncrementDefinitions(num_definitions);
	
	
	if (num_definitions > 0) {
			std::vector<SUComponentDefinitionRef> component_definitions(num_definitions);
			SUModelGetComponentDefinitions(model_, num_definitions, 
													 &component_definitions[0],
													 &num_definitions);

			for (size_t i = 0; i < num_definitions; i++) {
				SUComponentDefinitionRef component_definition =
						component_definitions[i];
				SUEntitiesRef entities2 = SU_INVALID;
				SUComponentDefinitionGetEntities(component_definitions[i], &entities2);
				out += count_all_components_entities(entities2);
			}
	}
	*/
	return out;
}
示例#5
0
/*
 * ==================
 * main
 * light modelfile
 * ==================
 */
int
main(int argc, const char **argv)
{
    int i, bsp_version;
    double start;
    double end;
    char source[1024];

    init_log("light.log");
    logprint("----- TyrLight v0.99e -----\n"
#if 0
	     "** Beta version " __DATE__ " " __TIME__ "\n"
#endif
	);

    numthreads = GetDefaultThreads();

    for (i = 1; i < argc; i++) {
	if (!strcmp(argv[i], "-threads")) {
	    numthreads = atoi(argv[i + 1]);
	    i++;
	} else if (!strcmp(argv[i], "-extra")) {
	    extrasamples = true;
	    logprint("extra sampling enabled\n");
	} else if (!strcmp(argv[i], "-dist")) {
	    scaledist = atof(argv[i + 1]);
	    i++;
	} else if (!strcmp(argv[i], "-range")) {
	    rangescale = atof(argv[i + 1]);
	    i++;
	} else if (!strcmp(argv[i], "-light")) {
	    worldminlight = atof(argv[i + 1]);
	    i++;
	} else if (!strcmp(argv[i], "-compress")) {
	    compress_ents = true;
	    logprint("light entity compression enabled\n");
	} else if (!strcmp(argv[i], "-colored") ||
		   !strcmp(argv[i], "-coloured")) {
	    colored = true;
	} else if (!strcmp(argv[i], "-bsp30")) {
	    bsp30 = true;
	} else if (!strcmp(argv[i], "-lit")) {
	    litfile = true;
	} else if (!strcmp(argv[i], "-nominlimit")) {
	    nominlimit = true;
	} else if (argv[i][0] == '-')
	    Error("Unknown option \"%s\"", argv[i]);
	else
	    break;
    }

    if (numthreads > 1)
	logprint("running with %d threads\n", numthreads);

    // Switch on colored flag if specifying -lit or -bsp30
    if (bsp30 || litfile)
	colored = true;

    // Check the colored options
    if (colored) {
	if (!bsp30 && !litfile) {
	    logprint("colored output format not specified -> using bsp 30\n");
	    bsp30 = true;
	} else if (bsp30 && litfile) {
	    Error("Two colored output formats specified");
	} else if (litfile) {
	    logprint("colored output format: lit\n");
	} else if (bsp30) {
	    logprint("colored output format: bsp30\n");
	}
    }

    if (i != argc - 1)
	Error("usage: light [-threads num] [-light num] [-extra]\n"
	      "             [-colored] [-bsp30] [-lit]\n"
	      "             [-nocount] [-compress] [-nominlimit] bspfile\n");

    start = I_FloatTime();

    strcpy(source, argv[i]);
    StripExtension(source);
    DefaultExtension(source, ".bsp");
    bsp_version = LoadBSPFile(source);

    LoadEntities();
    MakeTnodes();
    FindFaceOffsets();
    LightWorld();

    WriteEntitiesToString();

    if (colored && bsp30)
	WriteBSPFile(source, 30);
    else
	WriteBSPFile(source, bsp_version);

    if (colored && litfile)
	WriteLitFile(source, LIT_VERSION);

    end = I_FloatTime();
    logprint("%5.1f seconds elapsed\n", end - start);

    close_log();

    return 0;
}
示例#6
0
/*
========
main

light modelfile
========
*/
int main (int argc, char **argv)
{
	int		i;
	double		start, end;
	char		source[1024];

	printf ("----- LightFaces ----\n");

	for (i=1 ; i<argc ; i++)
	{
		if (!strcmp(argv[i],"-threads"))
		{
			numthreads = atoi (argv[i+1]);
			i++;
		}
		else if (!strcmp(argv[i],"-extra"))
		{
			extrasamples = true;
			printf ("extra sampling enabled\n");
		}
		else if (!strcmp(argv[i],"-dist"))
		{
			scaledist = atof (argv[i+1]);
			i++;
		}
		else if (!strcmp(argv[i],"-range"))
		{
			rangescale = atof (argv[i+1]);
			i++;
		}
		else if (argv[i][0] == '-')
			Error ("Unknown option \"%s\"", argv[i]);
		else
			break;
	}

	if (i != argc - 1)
		Error ("usage: light [-threads num] [-extra] bspfile");

	InitThreads ();

	start = I_FloatTime ();

	strcpy (source, argv[i]);
	StripExtension (source);
	DefaultExtension (source, ".bsp");
	
	LoadBSPFile (source);
	LoadEntities ();
		
	MakeTnodes (&dmodels[0]);

	LightWorld ();

	WriteEntitiesToString ();	
	WriteBSPFile (source);

	end = I_FloatTime ();
	printf ("%5.1f seconds elapsed\n", end-start);
	
	return 0;
}
示例#7
0
void dxModel::Load(const char * filename, bool fullpath)
{
    Free();

	FS_Change(FS_LOADING);

    loading_percent = 0;

    StrPool_Clear();

    DX_SAFE_FREE(mod_base); //free old map

    char fullfilename[MAX_PATH];

	if (fullpath)
	{
		static char temp[MAX_PATH];
		static char dirname[MAX_PATH];
		Str_ExtractDirName(filename, temp);
		Str_ExtractDirName(temp, dirname);

		Str_ExtractDirName(dirname, temp);

		strcat_s(temp, "\\valve");

		sysvar.basedir = dirname;
		sysvar.basedir_valve = temp;
		strcpy_s(fullfilename, filename);
	}
	else
	{
		sysvar.basedir = default_basedir;
		sysvar.basedir = default_basedir;
		sprintf_s(fullfilename, MAX_PATH, "%s\\maps\\%s.bsp", sysvar.basedir, filename);
	}
    

    FILE * f = NULL;
    fopen_s(&f, fullfilename, "rb");

    if (!f)
    {
        Sys_Error("could not open file %s", fullfilename);
    }

    fseek(f, 0, SEEK_END);
    long filesize = ftell(f);
    fseek(f, 0, SEEK_SET);

    mod_base = (char*)DX_MEM_ALLOC(filesize);
    if (!mod_base)
    {
        fclose(f);
        Sys_Error("could not alloc memory");
    }

    fread(mod_base, 1, filesize, f);
    fclose(f);

    dheader_s * header = (dheader_s*)mod_base;

    int v = Swap_LittleLong(header->version);
    if (v != BSPVERSION)
    {
        Sys_Error("bad bsp version");
    }

    for (int i = 0; i < HEADER_LUMPS; i++)
    {
        header->lumps[i].fileofs = Swap_LittleLong(header->lumps[i].fileofs);
        header->lumps[i].filelen = Swap_LittleLong(header->lumps[i].filelen);
    }

    UpdateLoadingPercent(6);

    //load entities first, we need wad file list
    LoadEntities(&header->lumps[LUMP_ENTITIES]);         UpdateLoadingPercent(12);
    LoadVertexes(&header->lumps[LUMP_VERTEXES]);         UpdateLoadingPercent(18);
    LoadEdges(&header->lumps[LUMP_EDGES]);               UpdateLoadingPercent(24);
    LoadSurfedges(&header->lumps[LUMP_SURFEDGES]);       UpdateLoadingPercent(30);
    LoadTextures(&header->lumps[LUMP_TEXTURES]);         UpdateLoadingPercent(36);
    LoadLighting(&header->lumps[LUMP_LIGHTING]);         UpdateLoadingPercent(42);
    LoadPlanes(&header->lumps[LUMP_PLANES]);             UpdateLoadingPercent(48);
    LoadTexinfo(&header->lumps[LUMP_TEXINFO]);           UpdateLoadingPercent(54);
    LoadFaces(&header->lumps[LUMP_FACES]);               UpdateLoadingPercent(60);
    LoadMarksurfaces(&header->lumps[LUMP_MARKSURFACES]); UpdateLoadingPercent(66);
    LoadVisibility(&header->lumps[LUMP_VISIBILITY]);     UpdateLoadingPercent(72);
    LoadLeafs(&header->lumps[LUMP_LEAFS]);               UpdateLoadingPercent(78);
    LoadNodes(&header->lumps[LUMP_NODES]);               UpdateLoadingPercent(84);
    LoadClipnodes(&header->lumps[LUMP_CLIPNODES]);       UpdateLoadingPercent(90);
    LoadSubmodels(&header->lumps[LUMP_MODELS]);          UpdateLoadingPercent(100);
    LoadSky();

    DX_SAFE_FREE(mod_base);

    visleafs = numleafs;
    if (numsubmodels > 0)
    {
        visleafs = submodels[0].visleafs;
    }

    InitViewer();

    loaded = true;

	FS_Change(FS_DEMO);
}
示例#8
0
/*
========
main

light modelfile
========
*/
int main (int argc, char **argv)
{
	int		i;
	int		wantthreads;
	double		start, end;
	char		source[1024];

	printf ("----- LightFaces ----\n");

	ValidateByteorder ();

	wantthreads = 1;	// default to single threaded

	for (i = 1 ; i < argc ; i++)
	{
		if (!strcmp(argv[i],"-threads"))
		{
			if (i >= argc - 1)
				COM_Error("Missing argument to \"%s\"", argv[i]);
			wantthreads = atoi (argv[++i]);
		}
		else if (!strcmp(argv[i],"-extra"))
		{
			extrasamples = true;
			printf ("extra sampling enabled\n");
		}
		else if (!strcmp(argv[i],"-dist"))
		{
			if (i >= argc - 1)
				COM_Error("Missing argument to \"%s\"", argv[i]);
			scaledist = (float)atof (argv[++i]);
		}
		else if (!strcmp(argv[i],"-range"))
		{
			if (i >= argc - 1)
				COM_Error("Missing argument to \"%s\"", argv[i]);
			rangescale = (float)atof (argv[++i]);
		}
		else if (argv[i][0] == '-')
			COM_Error ("Unknown option \"%s\"", argv[i]);
		else
			break;
	}

	if (i != argc - 1)
		COM_Error ("usage: light [-threads num] [-extra] [-dist ?] [-range ?] bspfile");

	InitThreads (wantthreads, 0);

	start = COM_GetTime ();

	strcpy (source, argv[i]);
	StripExtension (source);
	DefaultExtension (source, ".bsp", sizeof(source));

	LoadBSPFile (source);
	LoadEntities ();

	MakeTnodes (&dmodels[0]);

	LightWorld ();

	WriteEntitiesToString ();
	WriteBSPFile (source);

	end = COM_GetTime ();
	printf ("%5.1f seconds elapsed\n", end-start);

	return 0;
}
示例#9
0
/*
========
main

light modelfile
========
*/
int main (int argc, char **argv)
{
	int		i;
	double		start, end;
	char		source[1024];

	printf("Light.exe Version 1.3 Id Software and valve (%s)\n", __DATE__ );
	printf ("----- LightFaces ----\n");

	// default to 24-bit light info
	hicolor = true;

	for (i=1 ; i<argc ; i++)
	{
		if (!strcmp(argv[i],"-threads"))
		{
			numthreads = atoi (argv[i+1]);
			i++;
		}
		else if (!strcmp(argv[i],"-extra"))
		{
			extrasamples = true;
			printf ("extra sampling enabled\n");
		}
		else if (!strcmp(argv[i],"-dist"))
		{
			scaledist = atof (argv[i+1]);
			i++;
		}
		else if (!strcmp(argv[i],"-range"))
		{
			rangescale = atof (argv[i+1]);
			i++;
		}
		else if (!strcmp(argv[i],"-lowcolor"))
		{
			hicolor = false;
		}
		else if (!strcmp( argv[ i ], "-noclamp" ) )
		{
			clamp192 = false;
		}
		else if (argv[i][0] == '-')
			Error ("Unknown option \"%s\"", argv[i]);
		else
			break;
	}

	if (i != argc - 1)
		Error ("usage: light [-threads num] [-extra] [-lowcolor] bspfile");

	ThreadSetDefault ();

	start = I_FloatTime ();

	strcpy (source, argv[i]);
	StripExtension (source);
	DefaultExtension (source, ".bsp");
	
	LoadBSPFile (source);
	LoadEntities ();
		
	MakeTnodes (&dmodels[0]);

	LightWorld ();

	WriteBSPFile (source);

	end = I_FloatTime ();
	printf ("%5.1f seconds elapsed\n", end-start);
	
	return 0;
}
示例#10
0
/*
========
main

light modelfile
========
*/
int main (int argc, char **argv)
{
	int	 i, ModeCnt = 0, Val;
	char	 source[1024], *Option, *NextOption;
	float	 FVal;
	qboolean NoGlobRange = false;

	logfile = fopen (LOGFILENAME, "w");
	logprintf ("----- Light 1.43 ---- Modified by Bengt Jardrup\n");
	logprintf ("----- Release 2  ---- Coloured light and LIT support by MH\n\n");

	for (i = 1; i < argc; i++)
	{
		Option = argv[i];
		NextOption = i + 1 < argc ? argv[i + 1] : NULL;

		if (Option[0] != '-')
			break;

		++Option;

		if (!stricmp (Option, "fast"))
		{
			FastLight = 2;

			if (NextOption != NULL && isdigit (NextOption[0]) && i + 2 < argc)
			{
				Val = atoi (NextOption);
				i++;

				if (Val > 2)
					FastLight = Val;
			}

			logprintf ("Fast light %d enabled\n", FastLight);
		}
		else if (!stricmp (Option, "soft"))
		{
			SoftLight = 0;

			if (NextOption != NULL && isdigit (NextOption[0]) && i + 2 < argc)
			{
				SoftLight = atoi (NextOption);
				i++;
			}
		}
		else if (!stricmp (Option, "softdist"))
		{
			SoftDist = GetArgument (Option, NextOption);
			i++;
		}
		else if (!stricmp (Option, "extra") || !stricmp (Option, "extra4"))
		{
			OverSample = Option[5] == '4' ? 4 : 2;
			logprintf ("Extra %dx%d sampling enabled\n", OverSample, OverSample);
		}
		else if (!stricmp (Option, "threads"))
		{
			numthreads = GetFloatArgument (Option, NextOption);
			i++;
		}
		else if (!stricmp (Option, "dist"))
		{
			scaledist = GetFloatArgument (Option, NextOption);
			i++;
		}
		else if (!stricmp (Option, "range"))
		{
			rangescale = GetFloatArgument (Option, NextOption);
			i++;
		}
		else if (!stricmp (Option, "globrange"))
		{
			GlobRange = true;
			logprintf ("Global range enabled\n");
		}
		else if (!stricmp (Option, "noglobrange"))
			NoGlobRange = true;
		else if (!stricmp (Option, "light"))
		{
			worldminlight = GetArgument (Option, NextOption);
			i++;
		}
		else if (!stricmp (Option, "maxlight"))
		{
			worldmaxlight = GetArgument (Option, NextOption);
			i++;
		}
		else if (!stricmp (Option, "nolight"))
		{
			NoLight = true;
			logprintf ("Light entities disabled\n");
		}
		else if (!stricmp (Option, "srclight"))
		{
			SrcLight = true;
			logprintf ("Unsourced light entities disabled\n");
		}
		else if (!stricmp (Option, "sunlight"))
		{
			SunLight[0] = GetArgument (Option, NextOption);
			i++;
		}
		else if (!stricmp (Option, "sunlight2"))
		{
			SunLight[1] = GetArgument (Option, NextOption);
			i++;
		}
		else if (!stricmp (Option, "sunlight3"))
		{
			SunLight[1] = GetArgument (Option, NextOption);

			if (ShadowSense == -1)
				ShadowSense = SHADOWSENSE;

			i++;
		}
		else if (!stricmp (Option, "sunmangle"))
		{
			ChkArgument (Option, NextOption);

			if (sscanf (NextOption, "%d,%d", &SunMangleVal[0], &SunMangleVal[1]) != 2)
				Error ("Missing arguments for '%s'", Option);

			SunMangleVal[2] = 0;
			i++;
		}
		else if (!stricmp (Option, "nowarnings"))
			NoWarnings = true;
		else if (!stricmp (Option, "rate"))
		{
			ChkArgument (Option, NextOption);

			if (sscanf (NextOption, "%d,%f,%d,%d", &SecRate, &FVal, &NewLine, &TotTime) > 1)
				PercRate = (FVal + 0.05) * 10; // Fix roundoff

			AutoRate = false;
			i++;
		}
		else if (!stricmp (Option, "barpercent"))
		{
			SimpPercent = true;
			NumPercent = false;
		}
		else if (!stricmp (Option, "numpercent"))
		{
			SimpPercent = true;
			NumPercent = true;
		}
		else if (!stricmp (Option, "oldlight"))
		{
			OldLight = NoAnti = true;
			logprintf ("Oldlight mode enabled\n");
			++ModeCnt;
		}
		else if (!stricmp (Option, "tyrlite"))
		{
			TyrLiteMode = GlobRange = true;
			logprintf ("TyrLite mode enabled\n");
			++ModeCnt;
		}
		else if (!stricmp (Option, "tyrlite95"))
		{
			TyrLite95Mode = TyrLiteMode = GlobRange = true;
			logprintf ("TyrLite95 mode enabled\n");
			++ModeCnt;
		}
		else if (!stricmp (Option, "arghlite"))
		{
			ArghLiteMode = GlobRange = AddMinLight = true;
			logprintf ("ArghLite mode enabled\n");
			++ModeCnt;
		}
		else if (!stricmp (Option, "addmin"))
		{
			AddMinLight = true;
			logprintf ("Additive minlight enabled\n");
		}
		else if (!stricmp (Option, "iklite"))
		{
			IKLiteMode = IKAngle = OldLight = NoAnti = true;
			logprintf ("IKLite mode enabled\n");
			++ModeCnt;
		}
		else if (!stricmp (Option, "ikangle"))
		{
			IKAngle = true;
			logprintf ("IKLite angle sensitivity enabled\n");
		}
		else if (!stricmp (Option, "anglesense"))
		{
			FVal = GetFloatArgument (Option, NextOption);
			i++;

			if (FVal >= 0 && FVal <= 1 && FVal != scalecos)
				logprintf ("Angle sensitivity %g set\n", scalecos = FVal);
		}
		else if (!stricmp (Option, "shadowsense"))
		{
			FVal = GetFloatArgument (Option, NextOption);
			i++;

			if (FVal >= 0 && FVal <= 1)
				ShadowSense = FVal;
		}
		else if (!stricmp (Option, "gate"))
		{
			FVal = GetFloatArgument (Option, NextOption);
			i++;

			if (FVal >= 0 && FVal != GateVal)
				logprintf ("Fade Gate %g set\n", GateVal = FVal);
		}
		else if (!stricmp (Option, "dlx"))
		{
			LightDLXMode = OldLight = true;
			logprintf ("LightDLX mode enabled\n");
			++ModeCnt;
		}
		else if (!stricmp (Option, "kinn"))
		{
			KinnDelay = true;
			logprintf ("Kinn translation enabled\n");
		}
		else if (!stricmp (Option, "solidsky"))
		{
			SolidSky = true;
			logprintf ("Solid sky brushes enabled\n");
		}
		else if (!stricmp (Option, "unsup"))
			UnsupDetails = DetectKeys = true;
		else if (!stricmp (Option, "detect"))
			DetectKeys = true;
		else if (!stricmp (Option, "noskill"))
			NoSkillChk = true;
		else if (!stricmp (Option, "noflash"))
			NoFlash = true;
		else if (!stricmp (Option, "noanti"))
			NoAnti = NoAntiOption = true;
		else if (!stricmp (Option, "lightcap"))
		{
			Val = GetArgument (Option, NextOption);
			i++;

			if (Val >= 0 && Val != LightCap)
				logprintf ("LightCap %d enabled\n", LightCap = Val);
		}
		else if (!stricmp (Option, "onlyents"))
			OnlyEnts = true;
		else if (!stricmp (Option, "nowrite"))
			NoWrite = true;
		else if (!stricmp (Option, "norev"))
			NoReverse = true;
		else if (!stricmp (Option, "etp"))
		{
			EnhancedTP = true;
			logprintf ("Enhanced Texture Positioning enabled\n");
		}
		else if (!stricmp (Option, "priority"))
		{
			SetQPriority (GetArgument (Option, NextOption));
			i++;
		}
		else if (!stricmp (Option, "oldhformat"))
			OldHFormat = true;
		else if (!stricmp (Option, "?") || !stricmp (Option, "help"))
			PrintOptions ();
		else if (!stricmp (Option, "fakeGISun2"))
		{
			FakeGISunlight2 = true;
			logprintf ("Additive sunlight2 enabled\n");
		}
		else if (!stricmp (Option, "fakeGIMode"))
		{
			FakeGIMode = true;
			logprintf ("FakeGI mode enabled\n");
		}
		else
			Error ("Unknown option '%s'", Option);
	}

	if (i != argc - 1)
		PrintOptions ();

	if (GlobRange && NoGlobRange)
	{
		GlobRange = false;
		logprintf ("Global range disabled\n");
	}

	if (ModeCnt > 1)
		Error ("Only one emulation mode allowed");

	if (SoftLight >= 0)
	{
		if (SoftLight == 0)
			SoftLight = OverSample / 2 + 1; // Auto mode

		logprintf ("Soft light %d enabled\n", SoftLight);

		if (SoftDist != SOFTDIST)
			logprintf ("Soft distance %d set\n", SoftDist);
	}

	if (SoftLight > 0)
	{
		// Soft option is in charge
		SingleDist = -SoftDist;
		SkyDist = -SOFTDIST;
	}
	else
	{
		if (TyrLite95Mode)
		{
			SingleDist = 0;
			SkyDist = -ANGLE_EPSILON;
		}
		else
			SingleDist = SkyDist = 1; // Classic (no) soft distance
	}

	if (OverSample <= 2)
	{
		// Set compatibility modes
		GenCompatible = OldLight || TyrLiteMode || ArghLiteMode || IKLiteMode || LightDLXMode;
		ATCompatible = TyrLiteMode || ArghLiteMode;
		TyrCompatible = TyrLiteMode;
	}

	InitThreads ();

	if (!OnlyEnts && !NoWrite)
		start = I_FloatTime ();

	strcpy (source, argv[i]);
	StripExtension (source);
	DefaultExtension (source, ".bsp");

	if (!NoWrite)
		WriteChk (source);

	logprintf ("File: %s\n", source);

	LoadBSPFile (source);

	LoadEntities ();

	if (OnlyEnts)
		logprintf ("Updating entities lump...\n");
	else if (!NoWrite)
	{
		MakeTnodes (&dmodels[0]);

		FindFaceOffsets ();
		LightWorld ();
	}

	if (!NoWrite)
	{
		WriteEntitiesToString ();
		WriteBSPFile (source);
	}

	PrintFinish ();

	return 0;
}