예제 #1
0
파일: qe3.cpp 프로젝트: GSIO01/GtkRadiant
void QE_CheckAutoSave( void ){
	static time_t s_start;
	time_t now;
	time( &now );

	if ( modified != 1 || !s_start ) {
		s_start = now;
		return;
	}

	if ( ( now - s_start ) > ( 60 * g_PrefsDlg.m_nAutoSave ) ) {
		if ( g_PrefsDlg.m_bAutoSave ) {
			CString strMsg;
			strMsg = g_PrefsDlg.m_bSnapShots ? "Autosaving snapshot..." : "Autosaving...";
			Sys_Printf( strMsg );
			Sys_Printf( "\n" );
			Sys_Status( strMsg,0 );

			// only snapshot if not working on a default map
			if ( g_PrefsDlg.m_bSnapShots && stricmp( currentmap, "unnamed.map" ) != 0 ) {
				Map_Snapshot();
			}
			else
			{
				Map_SaveFile( ValueForKey( g_qeglobals.d_project_entity, "autosave" ), false );
			}

			Sys_Status( "Autosaving...Saved.", 0 );
			modified = 2;
		}
		else
		{
			Sys_Printf( "Autosave skipped...\n" );
			Sys_Status( "Autosave skipped...", 0 );
		}
		s_start = now;
	}
}
예제 #2
0
/*
====================
Entity_UpdateSoundEmitter

Deletes the soundEmitter if the entity should not emit a sound due
to it not having one, being filtered away, or the sound mode being turned off.

Creates or updates the soundEmitter if needed
====================
*/
void Entity_UpdateSoundEmitter( entity_t *ent )
{
    bool	playing = false;

    // if an entity doesn't have any brushes at all, don't do anything
    // if the brush isn't displayed (filtered or culled), don't do anything
    if ( g_pParentWnd->GetCamera()->GetSoundMode()
            && ent->brushes.onext != &ent->brushes && !FilterBrush(ent->brushes.onext) )
    {
        // check for sounds
        const char *v = ValueForKey( ent, "s_shader" );
        if ( v[0] )
        {
            refSound_t	sound;

            gameEdit->ParseSpawnArgsToRefSound( &ent->epairs, &sound );
            if ( !sound.waitfortrigger )  	// waitfortrigger will not start playing immediately
            {
                if ( !ent->soundEmitter )
                {
                    ent->soundEmitter = g_qeglobals.sw->AllocSoundEmitter();
                }
                playing = true;
                ent->soundEmitter->UpdateEmitter( ent->origin, 0, &sound.parms );
                // always play on a single channel, so updates always override
                ent->soundEmitter->StartSound( sound.shader, SCHANNEL_ONE );
            }
        }
    }

    // delete the soundEmitter if not used
    if ( !playing && ent->soundEmitter )
    {
        ent->soundEmitter->Free( true );
        ent->soundEmitter = NULL;
    }

}
예제 #3
0
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void DispGetFaceInfo( mapbrush_t *pBrush )
{
	int		i;
	side_t	*pSide;

	// we don't support displacement on entities at the moment!!
	if( pBrush->entitynum != 0 )
	{
		char* pszEntityName = ValueForKey( &entities[pBrush->entitynum], "classname" );
		Error( "Error: displacement found on a(n) %s entity - not supported\n", pszEntityName );
	}

	for( i = 0; i < pBrush->numsides; i++ )
	{
		pSide = &pBrush->original_sides[i];
		if( pSide->pMapDisp )
		{
			// error checking!!
			if( pSide->winding->numpoints != 4 )
				Error( "Trying to create a non-quad displacement!\n" );

			pSide->pMapDisp->face.originalface = pSide;
			pSide->pMapDisp->face.texinfo = pSide->texinfo;
			pSide->pMapDisp->face.dispinfo = -1;
			pSide->pMapDisp->face.planenum = pSide->planenum;
			pSide->pMapDisp->face.numpoints = pSide->winding->numpoints;
			pSide->pMapDisp->face.w = CopyWinding( pSide->winding );
			pSide->pMapDisp->face.contents = pBrush->contents;

			pSide->pMapDisp->face.merged = FALSE;
			pSide->pMapDisp->face.split[0] = FALSE;
			pSide->pMapDisp->face.split[1] = FALSE;

			pSide->pMapDisp->entitynum = pBrush->entitynum;
			pSide->pMapDisp->brushSideID = pSide->id;
		}
	}
}
예제 #4
0
//-----------------------------------------------------------------------------
// Compute the bounding box, excluding 3D skybox + skybox, add it to keyvalues
//-----------------------------------------------------------------------------
void ComputeBoundsNoSkybox( )
{
    // Iterate over all world leaves, skip those which are part of skybox
    Vector mins, maxs;
    ClearBounds (mins, maxs);
    AddNodeToBounds( dmodels[0].headnode, g_SkyAreas, mins, maxs );
    AddDispsToBounds( dmodels[0].headnode, g_SkyAreas, mins, maxs );

    // Add the bounds to the worldspawn data
    for (int i = 0; i < num_entities; ++i)
    {
        char* pEntity = ValueForKey(&entities[i], "classname");
        if (!strcmp(pEntity, "worldspawn"))
        {
            char	string[32];
            sprintf (string, "%i %i %i", (int)mins[0], (int)mins[1], (int)mins[2]);
            SetKeyValue (&entities[i], "world_mins", string);
            sprintf (string, "%i %i %i", (int)maxs[0], (int)maxs[1], (int)maxs[2]);
            SetKeyValue (&entities[i], "world_maxs", string);
            break;
        }
    }
}
예제 #5
0
static qboolean HasUniqueEntityName(const entity_t * ent, const char *name)
{
	int             i;
	entity_t       *ent2;
	const char     *name2;

	for(i = 0; i < numEntities; i++)
	{
		ent2 = &entities[i];

		if(ent == ent2)
			continue;

		name2 = ValueForKey(ent2, "name");

		if(!Q_stricmp(name, name2))
		{
			return qfalse;
		}
	}

	return qtrue;
}
예제 #6
0
vec_t   FloatForKey( entity_t *ent, char *key ) {
	char    *k;

	k = ValueForKey( ent, key );
	return atof( k );
}
예제 #7
0
/**
 * @brief Perform an entity check
 */
void CheckEntities (void)
{
	Check_InitEntityDefs();

	for (int i = 0; i < num_entities; i++) {
		entity_t* e = &entities[i];
		const char* name = ValueForKey(e, "classname");
		const entityDef_t* ed = ED_GetEntityDef(name);
		const epair_t* kvp;
		const entityKeyDef_t* kd;

		if (!ed) { /* check that a definition exists */
			Check_Printf(VERB_CHECK, false, i, -1, "Not defined in entities.ufo: %s\n", name);
			continue;
		}

		/* check alignment of info_.+_start */
		if (Check_IsInfoStart(name) && !Check_InfoStartAligned(ed, e))
			Check_Printf(VERB_CHECK, false, i, -1, "Misaligned %s\n", name);

		if (Q_strstart(name, "func_")) /* func_* entities should have brushes */
			Check_EntityWithBrushes(e, name, i);

		/* check all keys in the entity - make sure they are OK */
		for (kvp = e->epairs; kvp; kvp = kvp->next) {
			kd = ED_GetKeyDefEntity(ed, kvp->key, 0); /* zero means ignore abstract (radiant only) keys */

			if (!kd) { /* make sure it has a definition */
				Check_Printf(VERB_CHECK, false, i, -1, "Not defined in entities.ufo: %s in %s\n", kvp->key, name);
				continue;
			}

			if (ED_CheckKey(kd, kvp->value) == ED_ERROR) { /* check values against type and range definitions in entities.ufo */
				Check_Printf(VERB_CHECK, false, i, -1, "%s\n", ED_GetLastError());
				continue;
			}

			if (Q_streq("target", kvp->key) || Q_streq("targetname", kvp->key)) {
				if (!Check_TargetExists(kvp)) {
					Check_Printf(VERB_CHECK, false, i, -1,
						"%s with %s of %s: no corresponding entity with %s with matching value\n",
						ed->classname, kvp->key, kvp->value, Q_streq("target", kvp->key) ? "targetname" : "target");
				}
			}
		}

		/* check keys in the entity definition - make sure mandatory ones are present */
		for (kd = ed->keyDefs; kd->name; kd++) {
			if (kd->flags & ED_MANDATORY) {
				const char* keyNameInEnt = ValueForKey(e, kd->name);
				if (keyNameInEnt[0] == '\0') {
					const char* defaultVal = kd->defaultVal;
					const bool hasDefault = defaultVal ? true : false;
					Check_Printf(VERB_CHECK, hasDefault, i, -1, "Mandatory key missing from entity: %s in %s", kd->name, name);
					if (defaultVal) {
						Check_Printf(VERB_CHECK, hasDefault, i, -1, ", supplying default: %s", defaultVal);
						SetKeyValue(e, kd->name, defaultVal);
					}
					Check_Printf(VERB_CHECK, hasDefault, i, -1, "\n");
				}
			}
		}
	}
}
예제 #8
0
void RunBsp( char* command )
{
	char    sys[2048];
	char    batpath[2048];
	char    outputpath[2048];
	char    temppath[1024];
	char    name[2048];
	char    cWork[2048];
	FILE*   hFile;
	BOOL    ret;
	PROCESS_INFORMATION ProcessInformation;
	STARTUPINFO startupinfo;
	HWND hwndPClient = NULL;
	
	g_hWnd = g_pParentWnd->GetSafeHwnd();
	SetInspectorMode( W_CONSOLE );
	g_tBegin = CTime::GetCurrentTime();
	
	
	DWORD   dwExitcode;
	ret = GetExitCodeProcess( g_hToolThread, &dwExitcode );
	if ( dwExitcode != STILL_ACTIVE )
		g_hToolThread = NULL;
		
	if ( bsp_process || g_hToolThread )
	{
		Sys_Printf( "BSP is still going...\n" );
		return;
	}
	
	outputpath[0] = '\0';
	GetTempPath( 512, temppath );
	
	CString strOutFile = temppath;
	AddSlash( strOutFile );
	strOutFile += "junk.txt";
	
	sprintf( outputpath, " >>%s\r\n", strOutFile );
	
	strcpy( name, currentmap );
	if ( region_active )
	{
		Map_SaveFile( name, false );
		StripExtension( name );
		strcat( name, ".reg" );
	}
	
	Map_SaveFile( name, region_active );
	
	// FIXME: this code just gets worse and worse
	CString strPath, strFile;
	
	char* rsh = ValueForKey( g_qeglobals.d_project_entity, "rshcmd" );
	if ( rsh == NULL )
	{
		ExtractPath_and_Filename( name, strPath, strFile );
		AddSlash( strPath );
		BuildShortPathName( strPath, cWork, 1024 );
		strcat( cWork, strFile );
	}
	else
	{
		strcpy( cWork, name );
	}
	
	hwndPClient = FindWindow( NULL, "Q3Map Process Client" );
	if ( hwndPClient == NULL )
	{
		hwndPClient = FindAnyWindow( "Q3Map Process Client" );
	}
	
	Sys_Printf( "Window info for Process Client %i\n", reinterpret_cast<int>( hwndPClient ) );
	
	bool processServer = ( rsh && strlen( rsh ) > 0 && hwndPClient );
	
	QE_ExpandBspString( command, sys, cWork, processServer );
	
	// if we can find the q3map process server running
	// we will submit maps to it instead of via createprocess
	//
	if ( processServer )
	{
		CString str;
		char cBuff[2048];
		char* pStart = sys;
		char* pEnd = strstr( pStart, "&&" );
		while ( pEnd )
		{
			int nLen = pEnd - pStart - 1;
			strncpy( cBuff, pStart, nLen );
			cBuff[nLen] = 0;
			str = cBuff;
			FindReplace( str, rsh, "" );
			str.TrimLeft( ' ' );
			str.TrimRight( ' ' );
			ATOM a = GlobalAddAtom( str );
			PostMessage( hwndPClient, wm_AddCommand, 0, ( LPARAM )a );
			pStart = pEnd + 2;
			pEnd = strstr( pStart, "&&" );
		}
		str = pStart;
		FindReplace( str, rsh, "" );
		str.TrimLeft( ' ' );
		str.TrimRight( ' ' );
		ATOM a = GlobalAddAtom( str );
		PostMessage( hwndPClient, wm_AddCommand, 0, ( LPARAM )a );
		Sys_Printf( "Commands sent to Q3Map Process Client\n" );
		return;
	}
	
	CString strSys = sys;
	
	FindReplace( strSys, "&&", outputpath );
	strcpy( sys, strSys );
	strcat( sys, outputpath );
	
	
	Sys_ClearPrintf();
	Sys_Printf( "==================\nRunning bsp command...\n" );
	Sys_Printf( "\n%s\n", sys );
	
	//++timo removed the old way BSP commands .. dumping to junk.txt doesn't work on my win98 box
	// FIXME : will most likely break Quake2 BSP commands, is fitted to a one-lined sys command
	//
	// write qe3bsp.bat
	//
	//const char *basePath = ValueForKey(g_qeglobals.d_project_entity, "basepath");
	//if(basePath) {
	//const char *mapName =
	//sprintf(batpath,"%s/maps/%s.bat",basePath,mapName);
	strcpy( batpath, currentmap );
	char* dot = strchr( batpath, '.' );
	strcpy( dot, ".bat" );
	//} else {
	//  sprintf (batpath, "%sqe3bsp.bat", temppath);
	//}
	hFile = fopen( batpath, "w" );
	if ( !hFile )
		Error( "Can't write to %s", batpath );
	fprintf( hFile, sys );
	fclose( hFile );
	
	Pointfile_Delete();
	
	// delete junk.txt file
	remove( strOutFile );
	
	GetStartupInfo( &startupinfo );
	
	ret = CreateProcess(
			  batpath,
			  NULL,
			  NULL,
			  NULL,
			  FALSE,
			  0,
			  NULL,
			  NULL,
			  &startupinfo,
			  &ProcessInformation
		  );
		  
	if ( !ret )
		Error( "CreateProcess failed" );
		
	bsp_process = ProcessInformation.hProcess;
	
	Sleep( 100 );   // give the new process a chance to open it's window
	
	BringWindowToTop( g_qeglobals.d_hwndMain ); // pop us back on top
#if 0
	//
	// write qe3bsp.bat
	//
	sprintf( batpath, "%sqe3bsp.bat", temppath );
	hFile = fopen( batpath, "w" );
	if ( !hFile )
		Error( "Can't write to %s", batpath );
	fprintf( hFile, sys );
	fclose( hFile );
	
	//
	// write qe3bsp2.bat
	//
	sprintf( batpath, "%sqe3bsp2.bat", temppath );
	hFile = fopen( batpath, "w" );
	if ( !hFile )
		Error( "Can't write to %s", batpath );
	fprintf( hFile, "%sqe3bsp.bat > %s", temppath, outputpath );
	fclose( hFile );
	
	Pointfile_Delete();
	
	GetStartupInfo( &startupinfo );
	
	ret = CreateProcess(
			  batpath,      // pointer to name of executable module
			  NULL,         // pointer to command line string
			  NULL,         // pointer to process security attributes
			  NULL,         // pointer to thread security attributes
			  FALSE,            // handle inheritance flag
			  0 /*DETACHED_PROCESS*/,       // creation flags
			  NULL,         // pointer to new environment block
			  NULL,         // pointer to current directory name
			  &startupinfo, // pointer to STARTUPINFO
			  &ProcessInformation   // pointer to PROCESS_INFORMATION
		  );
		  
	if ( !ret )
		Error( "CreateProcess failed" );
		
	bsp_process = ProcessInformation.hProcess;
	
	Sleep( 100 );   // give the new process a chance to open it's window
	
	//BringWindowToTop( g_qeglobals.d_hwndMain );   // pop us back on top
	//SetFocus (g_qeglobals.d_hwndCamera);
#endif
	
}
예제 #9
0
/*
==================
CalcVis
==================
*/
void CalcVis(void)
{
	int             i, minvis, maxvis;
	const char     *value;
	double          mu, sigma, totalvis, totalvis2;


	/* ydnar: rr2do2's farplane code */
	farPlaneDist = 0.0f;
	value = ValueForKey(&entities[0], "_farplanedist");	/* proper '_' prefixed key */
	if(value[0] == '\0')
		value = ValueForKey(&entities[0], "fogclip");	/* wolf compatibility */
	if(value[0] == '\0')
		value = ValueForKey(&entities[0], "distancecull");	/* sof2 compatibility */
	if(value[0] != '\0')
	{
		farPlaneDist = atof(value);
		if(farPlaneDist > 0.0f)
			Sys_Printf("farplane distance = %.1f\n", farPlaneDist);
		else
			farPlaneDist = 0.0f;
	}



	Sys_Printf("\n--- BasePortalVis (%d) ---\n", numportals * 2);
	RunThreadsOnIndividual(numportals * 2, qtrue, BasePortalVis);

//  RunThreadsOnIndividual (numportals*2, qtrue, BetterPortalVis);

	SortPortals();

	if(fastvis)
	{
		CalcFastVis();
	}
	else if(noPassageVis)
	{
		CalcPortalVis();
	}
	else if(passageVisOnly)
	{
		CalcPassageVis();
	}
	else
	{
		CalcPassagePortalVis();
	}
	//
	// assemble the leaf vis lists by oring and compressing the portal lists
	//
	Sys_Printf("creating leaf vis...\n");
	for(i = 0; i < portalclusters; i++)
		ClusterMerge(i);

	totalvis = 0;
	totalvis2 = 0;
	minvis = -1;
	maxvis = -1;
	for(i = 0; i < MAX_MAP_LEAFS; ++i)
		if(clustersizehistogram[i])
		{
			if(debugCluster)
				Sys_FPrintf(SYS_VRB, "%4i clusters have exactly %4i visible clusters\n", clustersizehistogram[i], i);
			/* cast is to prevent integer overflow */
			totalvis += ((double)i) * ((double)clustersizehistogram[i]);
			totalvis2 += ((double)i) * ((double)i) * ((double)clustersizehistogram[i]);

			if(minvis < 0)
				minvis = i;
			maxvis = i;
		}

	mu = totalvis / portalclusters;
	sigma = sqrt(totalvis2 / portalclusters - mu * mu);

	Sys_Printf("Total clusters: %i\n", portalclusters);
	Sys_Printf("Total visible clusters: %.0f\n", totalvis);
	Sys_Printf("Average clusters visible: %.2f (%.3f%%/total)\n", mu, mu / portalclusters * 100.0);
	Sys_Printf("  Standard deviation: %.2f (%.3f%%/total, %.3f%%/avg)\n", sigma, sigma / portalclusters * 100.0,
			   sigma / mu * 100.0);
	Sys_Printf("  Minimum: %i (%.3f%%/total, %.3f%%/avg)\n", minvis, minvis / (double)portalclusters * 100.0,
			   minvis / mu * 100.0);
	Sys_Printf("  Maximum: %i (%.3f%%/total, %.3f%%/avg)\n", maxvis, maxvis / (double)portalclusters * 100.0,
			   maxvis / mu * 100.0);
}
예제 #10
0
파일: outside.c 프로젝트: LAxBANDA/cs16nd
/*
===========
FillOutside

===========
*/
node_t *FillOutside (node_t *node, qboolean leakfile)
{
    int			s;
    vec_t		*v;
    int			i;
    qboolean	inside;
    qboolean	ret;
    vec3_t		origin;
    char		*cl;

    qprintf ("----- FillOutside ----\n");

    if (nofill)
    {
        printf ("skipped\n");
        return node;
    }

    //
    // place markers for all entities so
    // we know if we leak inside
    //
    inside = false;
    for (i=1 ; i<num_entities ; i++)
    {
        GetVectorForKey (&entities[i], "origin", origin);
        if (!VectorCompare(origin, vec3_origin))
        {
            cl = ValueForKey (&entities[i], "classname");
            origin[2] += 1;	// so objects on floor are ok

            // nudge playerstart around if needed so clipping hulls allways
            // have a vlaid point
            if (!strcmp (cl, "info_player_start"))
            {
                int	x, y;

                for (x=-16 ; x<=16 ; x += 16)
                {
                    for (y=-16 ; y<=16 ; y += 16)
                    {
                        origin[0] += x;
                        origin[1] += y;
                        if (PlaceOccupant (i, origin, node))
                        {
                            inside = true;
                            goto gotit;
                        }
                        origin[0] -= x;
                        origin[1] -= y;
                    }
                }
gotit:
                ;
            }
            else
            {
                if (PlaceOccupant (i, origin, node))
                    inside = true;
            }
        }
    }

    if (!inside)
    {
        printf ("Hullnum %i: No entities in empty space -- no filling performed\n", hullnum);
        return node;
    }

    s = !(outside_node.portals->nodes[1] == &outside_node);

// first check to see if an occupied leaf is hit
    outleafs = 0;
    valid++;

    prevleaknode = NULL;

    if (leakfile)
    {
        pointfile = fopen (pointfilename, "w");
        if (!pointfile)
            Error ("Couldn't open %s\n", pointfilename);
        StripExtension (pointfilename);
        strcat (pointfilename, ".lin");
        linefile = fopen (pointfilename, "w");
        if (!linefile)
            Error ("Couldn't open %s\n", pointfilename);
    }

    ret = RecursiveFillOutside (outside_node.portals->nodes[s], false);

    if (leakfile)
    {
        fclose (pointfile);
        fclose (linefile);
    }

    if (ret)
    {
        printf("LEAK LEAK LEAK\n");
        GetVectorForKey (&entities[hit_occupied], "origin", origin);
        qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
        qprintf ("reached occupant at: (%4.0f,%4.0f,%4.0f)\n"
                 , origin[0], origin[1], origin[2]);
        qprintf ("no filling performed\n");
        qprintf ("point file and line file generated\n");
        qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
        if (leakonly)
            Error ("Stopped by leak.");
        return node;
    }

// now go back and fill things in
    valid++;
    RecursiveFillOutside (outside_node.portals->nodes[s], true);

// remove faces and nodes from filled in leafs
    c_falsenodes = 0;
    c_free_faces = 0;
    c_keep_faces = 0;
    node = ClearOutFaces_r (node);

    qprintf ("%5i outleafs\n", outleafs);
    qprintf ("%5i freed faces\n", c_free_faces);
    qprintf ("%5i keep faces\n", c_keep_faces);
    qprintf ("%5i falsenodes\n", c_falsenodes);

// save portal file for vis tracing
    if (leakfile)
        WritePortalfile (node);

    return node;
}
예제 #11
0
BOOL CALLBACK EditCommandDlgProc (
    HWND hwndDlg,	// handle to dialog box
    UINT uMsg,	// message
    WPARAM wParam,	// first message parameter
    LPARAM lParam 	// second message parameter
   )
{
	char	key[1024];
	char	value[1024];
	const char	*temp;
	int		index;
	HWND	hOwner;
	
	hOwner = GetParent (hwndDlg);

	switch (uMsg)
    {
	case WM_INITDIALOG:
		index = SendDlgItemMessage (hOwner, IDC_CMD_LIST, LB_GETCURSEL, 0, 0);
    if (index >= 0)
    {
		  SendDlgItemMessage(hOwner, IDC_CMD_LIST, LB_GETTEXT, index, (LPARAM) (LPCTSTR) key);
		  temp = ValueForKey (g_qeglobals.d_project_entity, key);
		  strcpy (value, temp);
		  SetDlgItemText(hwndDlg, IDC_CMDMENUTEXT, key);
		  SetDlgItemText(hwndDlg, IDC_CMDCOMMAND, value);
    }
		return FALSE;
		break;

	case WM_COMMAND: 
		switch (LOWORD(wParam)) 
		{ 
			case IDOK:
				if (!GetDlgItemText(hwndDlg, IDC_CMDMENUTEXT, key, 64))
				{
					common->Printf ("Command not added\n");
					return FALSE;
				}

				if (!GetDlgItemText(hwndDlg, IDC_CMDCOMMAND, value, 64))
				{
					common->Printf ("Command not added\n");
					return FALSE;
				}

				//if (key[0] == 'b' && key[1] == 's' && key[2] == 'p')
				//{
					SetKeyValue (g_qeglobals.d_project_entity, key, value);
					FillBSPMenu ();
				//}
				//else
				//	common->Printf ("BSP commands must be preceded by \"bsp\"");

				EndDialog(hwndDlg, 1);
				return TRUE;

			case IDCANCEL:
				EndDialog(hwndDlg, 0);
				return TRUE;
		}
	}
	return FALSE;
}
예제 #12
0
void Parse_Serverinfo(server_data *s, char *info)
{
    int i, j;
    char *pinfo;
    char *tmp;

    s->passed_filters = 1;
    s->support_teams = false; // by default server does't support team info per player

    if (strncmp(info, "\xFF\xFF\xFF\xFFn", 5))
    {
        SetPing(s, -1);
        return;
    }

    pinfo = strchr(info, '\n');
    if (pinfo != NULL)
        *(pinfo++) = 0;

    info += 5;

    while (*info == '\\'  &&  s->keysn < MAX_KEYS)
    {
        char *i2, *i3;
        i2 = strchr(info+1, '\\');
        if (i2 == NULL)
            break;
        i3 = strchr(i2+1, '\\');
        if (i3 == NULL)
            i3 = info + strlen(info);

        s->keys[s->keysn] = (char *) Q_malloc(i2-info);
        strlcpy(s->keys[s->keysn], info+1, i2-info);

        s->values[s->keysn] = (char *) Q_malloc(i3-i2);
        strlcpy(s->values[s->keysn], i2+1, i3-i2);

        s->keysn++;

        info = i3;
    }

    // read players

    for (i = s->spectatorsn = s->playersn = 0; pinfo  &&  strchr(pinfo, '\n'); i++)
    {
        qbool spec;
        int id, frags, time, ping, slen;
        char name[100], skin[100], team[100];
        char *nameptr = name;
        int top, bottom;
        int pos;

        if (s->playersn + s->spectatorsn >= MAX_PLAYERS)
            break;  // man

        pos = 0;
        pos += ReadInt(pinfo+pos, &id);
        pos += ReadInt(pinfo+pos, &frags);
        pos += ReadInt(pinfo+pos, &time);
        pos += ReadInt(pinfo+pos, &ping);
        pos += ReadString(pinfo+pos, name);
        pos += ReadString(pinfo+pos, skin);
        pos += ReadInt(pinfo+pos, &top);
        pos += ReadInt(pinfo+pos, &bottom);
        pos += ReadString(pinfo+pos, team);

        if (team[0])
            s->support_teams = true; // seems server support team info per player

        if (ping > 0) { // seems player if relay on ping
            spec = false;
            s->playersn++;
        }
        else // spec
        {
            spec = true;
            slen = strlen(name);
            s->spectatorsn++;
            ping = -ping;

            if (name[0] == '\\' && name[1] == 's' && name[2] == '\\')
                nameptr = name+3; // strip \s\<name>
            else if (slen > 3 && name[slen-3] == '(' && name[slen-2] == 's' && name[slen-1] == ')')
                name[slen-3] = 0; // strip <name>(s) for old servers
        }

        s->players[i] = (playerinfo *)Q_malloc(sizeof(playerinfo));
        s->players[i]->id = id;
        s->players[i]->frags = frags;
        s->players[i]->time = time;
        s->players[i]->ping = ping;
        s->players[i]->spec = spec;

        s->players[i]->top = Sbar_ColorForMap(top);
        s->players[i]->bottom = Sbar_ColorForMap(bottom);

        strlcpy(s->players[i]->name, nameptr, sizeof(s->players[0]->name));
        strlcpy(s->players[i]->skin, skin, sizeof(s->players[0]->skin));
        strlcpy(s->players[i]->team, team, sizeof(s->players[0]->team));

        pinfo = strchr(pinfo, '\n') + 1;
    }

    {
    void *swap;
    int n;
    // sort players by frags
    n = s->playersn + s->spectatorsn - 2;
    for (i = 0; i <= n; i++)
        for (j = n; j >= i; j--)
            if (s->players[j] && s->players[j+1] && s->players[j]->frags < s->players[j+1]->frags)
            {
                swap = (void*)s->players[j];
                s->players[j] = s->players[j+1];
                s->players[j+1] = (playerinfo*)swap;
            }
    // sort keys
    n = s->keysn - 2;
    for (i = 0; i <= n; i++)
        for (j = n; j >= i; j--)
            if (strcasecmp(s->keys[j], s->keys[j+1]) > 0)
            {
                swap = (void*)s->keys[j];
                s->keys[j] = s->keys[j+1];
                s->keys[j+1] = (char*)swap;
                swap = (void*)s->values[j];
                s->values[j] = s->values[j+1];
                s->values[j+1] = (char*)swap;
            }
    }

    // fill-in display
	s->qwfwd = SB_IsServerQWfwd(s);

    tmp = ValueForKey(s, "hostname");
    if (tmp != NULL)
        snprintf (s->display.name, sizeof (s->display.name),"%-.*s", COL_NAME, tmp);
    else
        return;

    tmp = ValueForKey(s, "fraglimit");
    if (tmp != NULL)
        snprintf(s->display.fraglimit, sizeof (s->display.fraglimit), "%*.*s", COL_FRAGLIMIT, COL_FRAGLIMIT, strlen(tmp) > COL_FRAGLIMIT ? "999" : tmp);

    tmp = ValueForKey(s, "timelimit");
    if (tmp != NULL)
        snprintf(s->display.timelimit, sizeof (s->display.timelimit), "%*.*s", COL_TIMELIMIT, COL_TIMELIMIT, strlen(tmp) > COL_TIMELIMIT ? "99" : tmp);

    tmp = ValueForKey(s, "*gamedir");
    s->qizmo = false;
    if (tmp != NULL)
        snprintf(s->display.gamedir, sizeof (s->display.gamedir) ,"%.*s", COL_GAMEDIR, tmp==NULL ? "" : tmp);
    else
    {
        tmp = ValueForKey(s, "*progs");
        if (tmp != NULL  &&  !strcmp(tmp, "666"))
        {
            snprintf(s->display.gamedir, sizeof (s->display.gamedir), "qizmo");
            s->qizmo = true;
        }
    }

    tmp = ValueForKey(s, "map");
    if (tmp != NULL)
        snprintf(s->display.map, sizeof (s->display.map), "%-.*s", COL_MAP, tmp==NULL ? "" : tmp);

    tmp = ValueForKey(s, "maxclients");
    if (!tmp || strlen(tmp) > 2)
        tmp = "99";
    i = s->playersn > 99 ? 99 : s->playersn;
    if (i < 1) { s->occupancy = SERVER_EMPTY; }
    else if (i > 0 && i < atoi(tmp)) { s->occupancy = SERVER_NONEMPTY; }
    else { s->occupancy = SERVER_FULL; }
    if (tmp != NULL)
        snprintf(s->display.players, sizeof (s->display.players), "%2d/%-2s", i, tmp==NULL ? "" : tmp);
}
예제 #13
0
파일: vis.cpp 프로젝트: sbenfold/zhlt-linux
// AJM: addded in
// =====================================================================================
//  GetParamsFromEnt
//      this function is called from parseentity when it encounters the 
//      info_compile_parameters entity. each tool should have its own version of this
//      to handle its own specific settings.
// =====================================================================================
void            GetParamsFromEnt(entity_t* mapent)
{
    int iTmp;

    Log("\nCompile Settings detected from info_compile_parameters entity\n");

    // verbose(choices) : "Verbose compile messages" : 0 = [ 0 : "Off" 1 : "On" ]
    iTmp = IntForKey(mapent, "verbose");
    if (iTmp == 1)
    {
        g_verbose = true;
    }
    else if (iTmp == 0)
    {
        g_verbose = false;
    }
    Log("%30s [ %-9s ]\n", "Compile Option", "setting");
    Log("%30s [ %-9s ]\n", "Verbose Compile Messages", g_verbose ? "on" : "off");

    // estimate(choices) :"Estimate Compile Times?" : 0 = [ 0: "Yes" 1: "No" ]
    if (IntForKey(mapent, "estimate")) 
    {
        g_estimate = true;
    }
    else
    {
        g_estimate = false;
    }
    Log("%30s [ %-9s ]\n", "Estimate Compile Times", g_estimate ? "on" : "off");

	// priority(choices) : "Priority Level" : 0 = [	0 : "Normal" 1 : "High"	-1 : "Low" ]
	if (!strcmp(ValueForKey(mapent, "priority"), "1"))
    {
        g_threadpriority = eThreadPriorityHigh;
        Log("%30s [ %-9s ]\n", "Thread Priority", "high");
    }
    else if (!strcmp(ValueForKey(mapent, "priority"), "-1"))
    {
        g_threadpriority = eThreadPriorityLow;
        Log("%30s [ %-9s ]\n", "Thread Priority", "low");
    }

    /*
    hlvis(choices) : "HLVIS" : 2 = 
    [ 
        0 : "Off"
        1 : "Fast"
        2 : "Normal" 
        3 : "Full"
    ]
    */
    iTmp = IntForKey(mapent, "hlvis");
    if (iTmp == 0)
    {
        Fatal(assume_TOOL_CANCEL, 
            "%s flag was not checked in info_compile_parameters entity, execution of %s cancelled", g_Program, g_Program);
        CheckFatal();   
    }
    else if (iTmp == 1)
    {
        g_fastvis = true;
        g_fullvis = false;
    }
    else if (iTmp == 2)
    {
        g_fastvis = false;
        g_fullvis = false;
    }
    else if (iTmp == 3)
    {
        g_fullvis = true;
        g_fastvis = false;
    }
    Log("%30s [ %-9s ]\n", "Fast VIS", g_fastvis ? "on" : "off"); 
    Log("%30s [ %-9s ]\n", "Full VIS", g_fullvis ? "on" : "off" );

    ///////////////////
    Log("\n");
}
예제 #14
0
파일: wad.c 프로젝트: AidHamza/eviltoys
void WriteMiptex (void)
{
	int i, success;
	byte *miptex_data;
	dmiptexlump_t *miptex_lumps;
	char *path, *currentpath;
	miptexfile_t *m;

	path = ValueForKey (&entities[0], "_wad");
	if (!path || !path[0])
	{
		path = ValueForKey (&entities[0], "wad");
		if (!path || !path[0])
		{
			printf ("WriteMiptex: no wads specified in \"wad\" key in worldspawn\n");
			texdatasize = 0;
			return;
		}
	}

	nummiptexfiles = 0;

	currentpath = path;
	while (*currentpath)
	{
		getwadname(wadname, &currentpath);
		if (wadname[0])
		{
			success = false;
			// try prepending each -wadpath on the commandline to the wad name
			for (i = 1;i < myargc;i++)
			{
				if (!Q_strcasecmp("-wadpath", myargv[i]))
				{
					i++;
					if (i < myargc)
					{
						sprintf(wadfilename, "%s%s", myargv[i], wadname);
						if ((success = loadwad(wadfilename) >= 0))
							break;
					}
				}
			}
			if (!success)
			{
				// if the map name has a path, we can try loading the wad from there
				ExtractFilePath(bspfilename, wadfilename);
				if (wadfilename[0])
				{
					strcat(wadfilename, wadname);
					if (!(success = loadwad(wadfilename) >= 0))
					{
						// try the parent directory
						ExtractFilePath(bspfilename, wadfilename);
						strcat(wadfilename, "../");
						strcat(wadfilename, wadname);
						success = loadwad(wadfilename) >= 0;
					}
				}
			}
			if (!success)
			{
				// try the wadname itself
				success = loadwad(wadname) >= 0;
			}
			if (!success)
				printf("Could not find wad \"%s\" using -wadpath options or in the same directory as the map or it's parent directory, so there!\n", wadname);
		}
	}

	for (i = 0;i < nummiptex;i++)
		CleanupName(miptex[i], miptex[i]);

	AddAnimatingTextures();

	miptex_lumps = (dmiptexlump_t *)dtexdata;
	miptex_data = (byte *)&miptex_lumps->dataofs[nummiptex];
	miptex_lumps->nummiptex = nummiptex;
	for (i=0 ; i < nummiptex ; i++)
	{
		printf("miptex used: %s", miptex[i]);
		m = FindMipTexFile(miptex[i]);
		if (m)
		{
			if (miptex_data + m->size - dtexdata >= MAX_MAP_MIPTEX)
			{
				miptex_lumps->dataofs[i] = -1;
				printf(" (MAX_MAP_MIPTEX exceeded)\n");
			}
			else if (ReadMipTexFile(m, miptex_data))
			{
				miptex_lumps->dataofs[i] = -1;
				printf(" (READ ERROR)\n");
			}
			else
			{
				miptex_lumps->dataofs[i] = miptex_data - (byte *)miptex_lumps;
				printf("\n");
				miptex_data += m->size;
			}
		}
		else
		{
			miptex_lumps->dataofs[i] = -1;
			printf(" (NOT FOUND)\n");
		}
	}

	texdatasize = miptex_data - dtexdata;
}
예제 #15
0
파일: portals.c 프로젝트: Diskutant/RTCW-SP
//===========================================================================
// Marks all nodes that can be reached by entites
//
// Parameter:               -
// Returns:                 -
// Changes Globals:     -
//===========================================================================
qboolean FloodEntities(tree_t *tree)
{
	int i;
	int x, y;
	vec3_t origin;
	char *cl;
	qboolean inside;
	node_t *headnode;

	headnode = tree->headnode;
	Log_Print("------ FloodEntities -------\n");
	inside = false;
	tree->outside_node.occupied = 0;

	//start at entity 1 not the world ( = 0)
	for(i = 1; i < num_entities; i++)
	{
		GetVectorForKey(&entities[i], "origin", origin);

		if(VectorCompare(origin, vec3_origin))
		{
			continue;
		}

		cl = ValueForKey(&entities[i], "classname");
		origin[2] += 1; //so objects on floor are ok

//		Log_Print("flooding from entity %d: %s\n", i, cl);
		//nudge playerstart around if needed so clipping hulls allways
		//have a valid point
		if(!strcmp(cl, "info_player_start"))
		{
			for(x = -16; x <= 16; x += 16)
			{
				for(y = -16; y <= 16; y += 16)
				{
					origin[0] += x;
					origin[1] += y;

					if(PlaceOccupant(headnode, origin, &entities[i]))
					{
						inside = true;
						x = 999; //stop for this info_player_start
						break;
					} //end if

					origin[0] -= x;
					origin[1] -= y;
				} //end for
			} //end for
		} //end if
		else
		{
			if(PlaceOccupant(headnode, origin, &entities[i]))
			{
				inside = true;
			} //end if
		} //end else
	} //end for

	if(!inside)
	{
		Log_Print("WARNING: no entities inside\n");
	} //end if
	else if(tree->outside_node.occupied)
	{
		Log_Print("WARNING: entity reached from outside\n");
	} //end else if

	return (qboolean)(inside && !tree->outside_node.occupied);
} //end of the function FloodEntities
예제 #16
0
파일: map.c 프로젝트: TTimo/GtkRadiant
/*
================
ParseMapEntity
================
*/
qboolean	ParseMapEntity (void)
{
	entity_t	*mapent;
	epair_t		*e;
	side_t		*s;
	int			i, j;
	int			startbrush, startsides;
	vec_t		newdist;
	mapbrush_t	*b;

	if (!GetToken (true))
		return false;

	if (strcmp (token, "{") )
		Error ("ParseEntity: { not found");
	
	if (num_entities == MAX_MAP_ENTITIES)
		Error ("num_entities == MAX_MAP_ENTITIES");

	startbrush = nummapbrushes;
	startsides = nummapbrushsides;

	mapent = &entities[num_entities];
	num_entities++;
	memset (mapent, 0, sizeof(*mapent));
	mapent->firstbrush = nummapbrushes;
	mapent->numbrushes = 0;
//	mapent->portalareas[0] = -1;
//	mapent->portalareas[1] = -1;

	do
	{
		if (!GetToken (true))
			Error ("ParseEntity: EOF without closing brace");
		if (!strcmp (token, "}") )
			break;
		if (!strcmp (token, "{") )
			ParseBrush (mapent);
		else
		{
			e = ParseEpair ();
			e->next = mapent->epairs;
			mapent->epairs = e;
		}
	} while (1);

	GetVectorForKey (mapent, "origin", mapent->origin);

	//
	// if there was an origin brush, offset all of the planes and texinfo
	//
	if (mapent->origin[0] || mapent->origin[1] || mapent->origin[2])
	{
		for (i=0 ; i<mapent->numbrushes ; i++)
		{
			b = &mapbrushes[mapent->firstbrush + i];
			for (j=0 ; j<b->numsides ; j++)
			{
				s = &b->original_sides[j];
				newdist = mapplanes[s->planenum].dist -
					DotProduct (mapplanes[s->planenum].normal, mapent->origin);
				s->planenum = FindFloatPlane (mapplanes[s->planenum].normal, newdist);
				s->texinfo = TexinfoForBrushTexture (&mapplanes[s->planenum],
					&side_brushtextures[s-brushsides], mapent->origin);
			}
			MakeBrushWindings (b);
		}
	}

	// group entities are just for editor convenience
	// toss all brushes into the world entity
	if (!strcmp ("func_group", ValueForKey (mapent, "classname")))
	{
		MoveBrushesToWorld (mapent);
		mapent->numbrushes = 0;
		return true;
	}

	// areaportal entities move their brushes, but don't eliminate
	// the entity
	if (!strcmp ("func_areaportal", ValueForKey (mapent, "classname")))
	{
		char	str[128];

		if (mapent->numbrushes != 1)
			Error ("Entity %i: func_areaportal can only be a single brush", num_entities-1);

		b = &mapbrushes[nummapbrushes-1];
		b->contents = CONTENTS_AREAPORTAL;
		c_areaportals++;
		mapent->areaportalnum = c_areaportals;
		// set the portal number as "style"
		sprintf (str, "%i", c_areaportals);
		SetKeyValue (mapent, "style", str);
		MoveBrushesToWorld (mapent);
		return true;
	}

	return true;
}
예제 #17
0
파일: fog.c 프로젝트: Elzair/q3map2
void CreateMapFogs( void ){
	int i;
	entity_t    *entity;
	brush_t     *brush;
	fog_t       *fog;
	vec3_t invFogDir;
	const char  *globalFog;


	/* skip? */
	if ( nofog ) {
		return;
	}

	/* note it */
	Sys_FPrintf( SYS_VRB, "--- CreateMapFogs ---\n" );

	/* walk entities */
	for ( i = 0; i < numEntities; i++ )
	{
		/* get entity */
		entity = &entities[ i ];

		/* walk entity brushes */
		for ( brush = entity->brushes; brush != NULL; brush = brush->next )
		{
			/* ignore non-fog brushes */
			if ( brush->contentShader->fogParms == qfalse ) {
				continue;
			}

			/* test limit */
			if ( numMapFogs >= MAX_MAP_FOGS ) {
				Error( "Exceeded MAX_MAP_FOGS (%d)", MAX_MAP_FOGS );
			}

			/* set up fog */
			fog = &mapFogs[ numMapFogs++ ];
			fog->si = brush->contentShader;
			fog->brush = brush;
			fog->visibleSide = -1;

			/* if shader specifies an explicit direction, then find a matching brush side with an opposed normal */
			if ( VectorLength( fog->si->fogDir ) ) {
				/* flip it */
				VectorScale( fog->si->fogDir, -1.0f, invFogDir );

				/* find the brush side */
				for ( i = 0; i < brush->numsides; i++ )
				{
					if ( VectorCompare( invFogDir, mapplanes[ brush->sides[ i ].planenum ].normal ) ) {
						fog->visibleSide = i;
						//%	Sys_Printf( "Brush num: %d Side num: %d\n", fog->brushNum, fog->visibleSide );
						break;
					}
				}
			}
		}
	}

	/* ydnar: global fog */
	globalFog = ValueForKey( &entities[ 0 ], "_fog" );
	if ( globalFog[ 0 ] == '\0' ) {
		globalFog = ValueForKey( &entities[ 0 ], "fog" );
	}
	if ( globalFog[ 0 ] != '\0' ) {
		/* test limit */
		if ( numMapFogs >= MAX_MAP_FOGS ) {
			Error( "Exceeded MAX_MAP_FOGS (%d) trying to add global fog", MAX_MAP_FOGS );
		}

		/* note it */
		Sys_FPrintf( SYS_VRB, "Map has global fog shader %s\n", globalFog );

		/* set up fog */
		fog = &mapFogs[ numMapFogs++ ];
		fog->si = ShaderInfoForShaderNull( globalFog );
		if ( fog->si == NULL ) {
			Error( "Invalid shader \"%s\" referenced trying to add global fog", globalFog );
		}
		fog->brush = NULL;
		fog->visibleSide = -1;

		/* set as default fog */
		defaultFogNum = numMapFogs - 1;

		/* mark all worldspawn brushes as fogged */
		for ( brush = entities[ 0 ].brushes; brush != NULL; brush = brush->next )
			ApplySurfaceParm( "fog", &brush->contentFlags, NULL, &brush->compileFlags );
	}

	/* emit some stats */
	Sys_FPrintf( SYS_VRB, "%9d fogs\n", numMapFogs );
}
예제 #18
0
void CheckBspProcess( void )
{
	char    outputpath[1024];
	char    temppath[512];
	DWORD   exitcode;
	char*   out;
	BOOL    ret;
	
	if ( !bsp_process )
		return;
		
	ret = GetExitCodeProcess( bsp_process, &exitcode );
	if ( !ret )
		Error( "GetExitCodeProcess failed" );
	if ( exitcode == STILL_ACTIVE )
		return;
		
	bsp_process = 0;
	
	GetTempPath( 512, temppath );
	sprintf( outputpath, "%sjunk.txt", temppath );
	
	LoadFile( outputpath, ( void** )&out );
	Sys_Printf( "%s", out );
	Sys_Printf( "\ncompleted.\n" );
	free( out );
	
	CTime tEnd = CTime::GetCurrentTime();
	CTimeSpan tElapsed = tEnd - g_tBegin;
	CString strElapsed;
	strElapsed.Format( "Run time was %i hours, %i minutes and %i seconds", tElapsed.GetHours(), tElapsed.GetMinutes(), tElapsed.GetSeconds() );
	Sys_Printf( strElapsed.GetBuffer( 0 ) );
	
	
	Sys_Beep();
	Pointfile_Check();
	// run game if no PointFile and pref is set
	//++timo needs to stop after BSP if leaked .. does run through vis and light instead ..
	if ( g_PrefsDlg.m_bRunQuake == TRUE  && !g_qeglobals.d_pointfile_display_list )
	{
		char cCurDir[1024];
		GetCurrentDirectory( 1024, cCurDir );
		CString strExePath = "../../qio.exe";
		//= g_PrefsDlg.m_strQuake2;
		CString strOrgPath;
		CString strOrgFile;
		ExtractPath_and_Filename( currentmap, strOrgPath, strOrgFile );
		if ( g_PrefsDlg.m_bSetGame == TRUE )  // run in place with set game.. don't copy map
		{
			CString strBasePath = ValueForKey( g_qeglobals.d_project_entity, "basepath" );
			strExePath += " +set game ";
			strExePath += strBasePath;
			WinExec( strExePath, SW_SHOW );
		}
		else
		{
			CString strCopyPath = strExePath;
			char* pBuffer = strCopyPath.GetBufferSetLength( _MAX_PATH + 1 );
			pBuffer[strCopyPath.ReverseFind( '\\' ) + 1] = '\0';
			strCopyPath.ReleaseBuffer();
			SetCurrentDirectory( strCopyPath );
			CString strOrgPath;
			CString strOrgFile;
			ExtractPath_and_Filename( currentmap, strOrgPath, strOrgFile );
			AddSlash( strCopyPath );
			FindReplace( strOrgFile, ".map", ".bsp" );
			//++timo modified for Quake3 !!
			strCopyPath += "baseq3\\maps\\";
			strCopyPath += strOrgFile;
			AddSlash( strOrgPath );
			strOrgPath += strOrgFile;
			bool bRun = ( strOrgPath.CompareNoCase( strCopyPath ) == 0 );
			if ( !bRun )
				bRun = ( CopyFile( strOrgPath, strCopyPath, FALSE ) == TRUE );
			if ( bRun )
			{
				FindReplace( strOrgFile, ".bsp", "" );
				strExePath += " +map ";
				strExePath += strOrgFile;
				WinExec( strExePath, SW_SHOW );
			}
		}
		SetCurrentDirectory( cCurDir );
	}
}
예제 #19
0
void QE_ExpandBspString( char* bspaction, char* out, char* mapname, bool useTemps )
{
	char*   in;
	char    src[2048];
	char    rsh[2048];
	char    base[2048];
	const char* basePath;
	const char* modDir;
	
	strcpy( src, mapname );
	strlwr( src );
	in = strstr( src, "maps/" );
	if ( !in )
	{
		in = strstr( src, "maps\\" );
	}
	if ( in )
	{
		in += 5;
		strcpy( base, in );
		in = base;
		while ( *in )
		{
			if ( *in == '\\' )
			{
				*in = '/';
			}
			in++;
		}
	}
	else
	{
		ExtractFileName( mapname, base );
	}
	
	if ( useTemps )
	{
		CString str;
		CString strExt = "map";
		if ( strstr( mapname, ".reg" ) )
		{
			strExt = "reg";
		}
		str.Format( "%s/maps/%i.%s", ValueForKey( g_qeglobals.d_project_entity, "remotebasepath" ), ::GetTickCount(), strExt );
		CopyFile( mapname, str, FALSE );
		sprintf( src, "-tempname %s %s/maps/%s", str, ValueForKey( g_qeglobals.d_project_entity, "remotebasepath" ), base );
	}
	else
	{
		sprintf( src, "%s/maps/%s", ValueForKey( g_qeglobals.d_project_entity, "remotebasepath" ), base );
	}
	strcpy( rsh, ValueForKey( g_qeglobals.d_project_entity, "rshcmd" ) );
	
	QE_ConvertDOSToUnixName( src, src );
	
	in = ValueForKey( g_qeglobals.d_project_entity, bspaction );
	basePath = ValueForKey( g_qeglobals.d_project_entity, "basepath" );
	modDir = ValueForKey( g_qeglobals.d_project_entity, "moddir" );
	if ( modDir[0] == '/' || modDir[0] == '\\' )
		modDir++;
	while ( *in )
	{
		if ( in[0] == '!' )
		{
			strcpy( out, rsh );
			out += strlen( rsh );
			in++;
			continue;
		}
		if ( in[0] == '$' )
		{
			strcpy( out, "-gamedir " );
			out += strlen( "-gamedir " );
			strcpy( out, basePath );
			out += strlen( basePath );
			//strcpy(out,modDir);
			//out += strlen(modDir);
			
			*out = ' ';
			out++;
			strcpy( out, src );
			out += strlen( src );
			in++;
			continue;
		}
		if ( in[0] == '@' )
		{
			*out++ = '"';
			in++;
			continue;
		}
		*out++ = *in++;
	}
	*out = 0;
}
예제 #20
0
파일: bsp.c 프로젝트: Teivaz/nebula2
void ProcessWorldModel( void )
{
    int            i, s;
    entity_t    *e;
    tree_t        *tree;
    face_t        *faces;
    qboolean    ignoreLeaks, leaked;
    xmlNodePtr    polyline, leaknode;
    char        level[ 2 ], shader[ 1024 ];
    const char    *value;
    
    
    /* sets integer blockSize from worldspawn "_blocksize" key if it exists */
    value = ValueForKey( &entities[ 0 ], "_blocksize" );
    if( value[ 0 ] == '\0' )
        value = ValueForKey( &entities[ 0 ], "blocksize" );
    if( value[ 0 ] == '\0' )
        value = ValueForKey( &entities[ 0 ], "chopsize" );    /* sof2 */
    if( value[ 0 ] != '\0' )
    {
        /* scan 3 numbers */
        s = sscanf( value, "%d %d %d", &blockSize[ 0 ], &blockSize[ 1 ], &blockSize[ 2 ] );
        
        /* handle legacy case */
        if( s == 1 )
        {
            blockSize[ 1 ] = blockSize[ 0 ];
            blockSize[ 2 ] = blockSize[ 0 ];
        }
    }
    Sys_Printf( "block size = { %d %d %d }\n", blockSize[ 0 ], blockSize[ 1 ], blockSize[ 2 ] );
    
    /* sof2: ignore leaks? */
    value = ValueForKey( &entities[ 0 ], "_ignoreleaks" );    /* ydnar */
    if( value[ 0 ] == '\0' )
        value = ValueForKey( &entities[ 0 ], "ignoreleaks" );
    if( value[ 0 ] == '1' )
        ignoreLeaks = qtrue;
    else
        ignoreLeaks = qfalse;
    
    /* begin worldspawn model */
    BeginModel();
    e = &entities[ 0 ];
    e->firstDrawSurf = 0;
    
    /* ydnar: gs mods */
    ClearMetaTriangles();

    /* check for patches with adjacent edges that need to lod together */
    PatchMapDrawSurfs( e );

    /* build an initial bsp tree using all of the sides of all of the structural brushes */
    faces = MakeStructuralBSPFaceList( entities[ 0 ].brushes );
    tree = FaceBSP( faces );
    MakeTreePortals( tree );
    FilterStructuralBrushesIntoTree( e, tree );
    
    /* see if the bsp is completely enclosed */
    if( FloodEntities( tree ) || ignoreLeaks )
    {
        /* rebuild a better bsp tree using only the sides that are visible from the inside */
        FillOutside( tree->headnode );

        /* chop the sides to the convex hull of their visible fragments, giving us the smallest polygons */
        ClipSidesIntoTree( e, tree );
        
        /* build a visible face tree */
        faces = MakeVisibleBSPFaceList( entities[ 0 ].brushes );
        FreeTree( tree );
        tree = FaceBSP( faces );
        MakeTreePortals( tree );
        FilterStructuralBrushesIntoTree( e, tree );
        leaked = qfalse;
        
        /* ydnar: flood again for skybox */
        if( skyboxPresent )
            FloodEntities( tree );
    }
    else
    {
        Sys_FPrintf( SYS_NOXML, "**********************\n" );
        Sys_FPrintf( SYS_NOXML, "******* leaked *******\n" );
        Sys_FPrintf( SYS_NOXML, "**********************\n" );
        polyline = LeakFile( tree );
        leaknode = xmlNewNode( NULL, "message" );
        xmlNodeSetContent( leaknode, "MAP LEAKED\n" );
        xmlAddChild( leaknode, polyline );
        level[0] = (int) '0' + SYS_ERR;
        level[1] = 0;
        xmlSetProp( leaknode, "level", (char*) &level );
        xml_SendNode( leaknode );
        if( leaktest )
        {
            Sys_Printf ("--- MAP LEAKED, ABORTING LEAKTEST ---\n");
            exit( 0 );
        }
        leaked = qtrue;
        
        /* chop the sides to the convex hull of their visible fragments, giving us the smallest polygons */
        ClipSidesIntoTree( e, tree );
    }
    
    /* save out information for visibility processing */
    NumberClusters( tree );
    if( !leaked )
        WritePortalFile( tree );
    
    /* flood from entities */
    FloodAreas( tree );
    
    /* create drawsurfs for triangle models */
    AddTriangleModels( e );
    
    /* create drawsurfs for surface models */
    AddEntitySurfaceModels( e );
    
    /* generate bsp brushes from map brushes */
    EmitBrushes( e->brushes, &e->firstBrush, &e->numBrushes );
    
    /* add references to the detail brushes */
    FilterDetailBrushesIntoTree( e, tree );
    
    /* drawsurfs that cross fog boundaries will need to be split along the fog boundary */
    if( !nofog )
        FogDrawSurfaces( e );
    
    /* subdivide each drawsurf as required by shader tesselation */
    if( !nosubdivide )
        SubdivideFaceSurfaces( e, tree );
    
    /* add in any vertexes required to fix t-junctions */
    if( !notjunc )
        FixTJunctions( e );
    
    /* ydnar: classify the surfaces */
    ClassifyEntitySurfaces( e );
    
    /* ydnar: project decals */
    MakeEntityDecals( e );
    
    /* ydnar: meta surfaces */
    MakeEntityMetaTriangles( e );
    SmoothMetaTriangles();
    FixMetaTJunctions();
    MergeMetaTriangles();
    
    /* ydnar: debug portals */
    if( debugPortals )
        MakeDebugPortalSurfs( tree );
    
    /* ydnar: fog hull */
    value = ValueForKey( &entities[ 0 ], "_foghull" );
    if( value[ 0 ] != '\0' )
    {
        sprintf( shader, "textures/%s", value );
        MakeFogHullSurfs( e, tree, shader );
    }
    
    /* ydnar: bug 645: do flares for lights */
    for( i = 0; i < numEntities && emitFlares; i++ )
    {
        entity_t    *light, *target;
        const char    *value, *flareShader;
        vec3_t        origin, targetOrigin, normal, color;
        int            lightStyle;
        
        
        /* get light */
        light = &entities[ i ];
        value = ValueForKey( light, "classname" );
        if( !strcmp( value, "light" ) )
        {
            /* get flare shader */
            flareShader = ValueForKey( light, "_flareshader" );
            value = ValueForKey( light, "_flare" );
            if( flareShader[ 0 ] != '\0' || value[ 0 ] != '\0' )
            {
                /* get specifics */
                GetVectorForKey( light, "origin", origin );
                GetVectorForKey( light, "_color", color );
                lightStyle = IntForKey( light, "_style" );
                if( lightStyle == 0 )
                    lightStyle = IntForKey( light, "style" );
                
                /* handle directional spotlights */
                value = ValueForKey( light, "target" );
                if( value[ 0 ] != '\0' )
                {
                    /* get target light */
                    target = FindTargetEntity( value );
                    if( target != NULL )
                    {
                        GetVectorForKey( target, "origin", targetOrigin );
                        VectorSubtract( targetOrigin, origin, normal );
                        VectorNormalize( normal, normal );
                    }
                }
                else
                    //%    VectorClear( normal );
                    VectorSet( normal, 0, 0, -1 );
                
                /* create the flare surface (note shader defaults automatically) */
                DrawSurfaceForFlare( mapEntityNum, origin, normal, color, (char*) flareShader, lightStyle );
            }
        }
    }
    
    /* add references to the final drawsurfs in the apropriate clusters */
    FilterDrawsurfsIntoTree( e, tree );
    
    /* match drawsurfaces back to original brushsides (sof2) */
    FixBrushSides( e );
    
    /* finish */
    EndModel( e, tree->headnode );
    FreeTree( tree );
}
예제 #21
0
파일: bsp.c 프로젝트: Teivaz/nebula2
static void SetCloneModelNumbers( void )
{
    int            i, j;
    int            models;
    char        modelValue[ 10 ];
    const char    *value, *value2, *value3;
    
    
    /* start with 1 (worldspawn is model 0) */
    models = 1;
    for( i = 1; i < numEntities; i++ )
    {
        /* only entities with brushes or patches get a model number */
        if( entities[ i ].brushes == NULL && entities[ i ].patches == NULL )
            continue;
        
        /* is this a clone? */
        value = ValueForKey( &entities[ i ], "_clone" );
        if( value[ 0 ] != '\0' )
            continue;
        
        /* add the model key */
        sprintf( modelValue, "*%d", models );
        SetKeyValue( &entities[ i ], "model", modelValue );
        
        /* increment model count */
        models++;
    }
    
    /* fix up clones */
    for( i = 1; i < numEntities; i++ )
    {
        /* only entities with brushes or patches get a model number */
        if( entities[ i ].brushes == NULL && entities[ i ].patches == NULL )
            continue;
        
        /* is this a clone? */
        value = ValueForKey( &entities[ i ], "_ins" );
        if( value[ 0 ] == '\0' )
            value = ValueForKey( &entities[ i ], "_instance" );
        if( value[ 0 ] == '\0' )
            value = ValueForKey( &entities[ i ], "_clone" );
        if( value[ 0 ] == '\0' )
            continue;
        
        /* find an entity with matching clone name */
        for( j = 0; j < numEntities; j++ )
        {
            /* is this a clone parent? */
            value2 = ValueForKey( &entities[ j ], "_clonename" );
            if( value2[ 0 ] == '\0' )
                continue;
            
            /* do they match? */
            if( strcmp( value, value2 ) == 0 )
            {
                /* get the model num */
                value3 = ValueForKey( &entities[ j ], "model" );
                if( value3[ 0 ] == '\0' )
                {
                    Sys_Printf( "WARNING: Cloned entity %s referenced entity without model\n", value2 );
                    continue;
                }
                models = atoi( &value2[ 1 ] );
                
                /* add the model key */
                sprintf( modelValue, "*%d", models );
                SetKeyValue( &entities[ i ], "model", modelValue );
                
                /* nuke the brushes/patches for this entity (fixme: leak!) */
                entities[ i ].brushes = NULL;
                entities[ i ].patches = NULL;
            }
        }
    }
}
예제 #22
0
static void PopulateTraceNodes(void)
{
	int             i, m, frame, castShadows;
	float           temp;
	entity_t       *e;
	const char     *value;
	picoModel_t    *model;
	vec3_t          origin, scale, angles;
	matrix_t        rotation;
	matrix_t        transform;


	/* add worldspawn triangles */
	MatrixIdentity(transform);
	PopulateWithBSPModel(&bspModels[0], transform);

	/* walk each entity list */
	for(i = 1; i < numEntities; i++)
	{
		/* get entity */
		e = &entities[i];

		/* get shadow flags */
		castShadows = ENTITY_CAST_SHADOWS;
		GetEntityShadowFlags(e, NULL, &castShadows, NULL);

		/* early out? */
		if(!castShadows)
			continue;

		/* get entity origin */
		GetVectorForKey(e, "origin", origin);

		/* get "angle" (yaw) or "angles" (pitch yaw roll) */
		MatrixIdentity(rotation);
		angles[0] = angles[1] = angles[2] = 0.0f;

		value = ValueForKey(e, "angle");
		if(value[0] != '\0')
		{
			angles[1] = atof(value);
			MatrixFromAngles(rotation, angles[PITCH], angles[YAW], angles[ROLL]);
		}

		value = ValueForKey(e, "angles");
		if(value[0] != '\0')
		{
			sscanf(value, "%f %f %f", &angles[0], &angles[1], &angles[2]);
			MatrixFromAngles(rotation, angles[PITCH], angles[YAW], angles[ROLL]);
		}

		value = ValueForKey(e, "rotation");
		if(value[0] != '\0')
		{
			sscanf(value, "%f %f %f %f %f %f %f %f %f", &rotation[0], &rotation[1], &rotation[2],
				   &rotation[4], &rotation[5], &rotation[6], &rotation[8], &rotation[9], &rotation[10]);
		}

		/* get scale */
		scale[0] = scale[1] = scale[2] = 1.0f;
		temp = FloatForKey(e, "modelscale");
		if(temp != 0.0f)
			scale[0] = scale[1] = scale[2] = temp;
		value = ValueForKey(e, "modelscale_vec");
		if(value[0] != '\0')
			sscanf(value, "%f %f %f", &scale[0], &scale[1], &scale[2]);

		MatrixMultiplyScale(rotation, scale[0], scale[1], scale[2]);

		/* set transform matrix */
		MatrixIdentity(transform);
		MatrixSetupTransformFromRotation(transform, rotation, origin);

		//% m4x4_pivoted_transform_by_vec3(transform, origin, angles, eXYZ, scale, vec3_origin);

		/* get model */
		value = ValueForKey(e, "model");

		/* switch on model type */
		switch (value[0])
		{
				/* no model */
			case '\0':
				break;

				/* bsp model */
			case '*':
				m = atoi(&value[1]);
				if(m <= 0 || m >= numBSPModels)
					continue;
				PopulateWithBSPModel(&bspModels[m], transform);
				break;

				/* external model */
			default:
				frame = IntForKey(e, "_frame");
				model = LoadModel((char *)value, frame);
				if(model == NULL)
					continue;
				PopulateWithPicoModel(castShadows, model, transform);
				continue;
		}

		/* get model2 */
		value = ValueForKey(e, "model2");

		/* switch on model type */
		switch (value[0])
		{
				/* no model */
			case '\0':
				break;

				/* bsp model */
			case '*':
				m = atoi(&value[1]);
				if(m <= 0 || m >= numBSPModels)
					continue;
				PopulateWithBSPModel(&bspModels[m], transform);
				break;

				/* external model */
			default:
				frame = IntForKey(e, "_frame2");
				model = LoadModel((char *)value, frame);
				if(model == NULL)
					continue;
				PopulateWithPicoModel(castShadows, model, transform);
				continue;
		}
	}
}
예제 #23
0
// FIXME: turn this into an MFC dialog
BOOL CALLBACK ProjectDlgProc (
    HWND hwndDlg,	// handle to dialog box
    UINT uMsg,	// message
    WPARAM wParam,	// first message parameter
    LPARAM lParam 	// second message parameter
   )
{
	char		key[1024];
	char		value[1024];
	int			index;

	switch (uMsg)
    {
	case WM_INITDIALOG:
		SetDlgItemText(hwndDlg, IDC_PRJBASEPATH, ValueForKey (g_qeglobals.d_project_entity, "basepath"));
		SetDlgItemText(hwndDlg, IDC_PRJMAPSPATH, ValueForKey (g_qeglobals.d_project_entity, "mapspath"));
		SetDlgItemText(hwndDlg, IDC_PRJRSHCMD, ValueForKey (g_qeglobals.d_project_entity, "rshcmd"));
		SetDlgItemText(hwndDlg, IDC_PRJREMOTEBASE, ValueForKey (g_qeglobals.d_project_entity, "remotebasepath"));
		SetDlgItemText(hwndDlg, IDC_PRJENTITYPATH, ValueForKey (g_qeglobals.d_project_entity, "entitypath"));
		SetDlgItemText(hwndDlg, IDC_PRJTEXPATH, ValueForKey (g_qeglobals.d_project_entity, "texturepath"));
		UpdateBSPCommandList (hwndDlg);
		// Timo
		// additional fields
		CheckDlgButton( hwndDlg, IDC_CHECK_BPRIMIT, (g_qeglobals.m_bBrushPrimitMode) ? BST_CHECKED : BST_UNCHECKED );
//		SendMessage( ::GetDlgItem( hwndDlg, IDC_CHECK_BPRIMIT ), BM_SETCHECK, (WPARAM) g_qeglobals.m_bBrushPrimitMode, 0 );
		return TRUE;

	case WM_COMMAND: 
		switch (LOWORD(wParam)) 
		{ 
			case IDC_ADDCMD:
//				DialogBox(g_qeglobals.d_hInstance, (char *)IDD_ADDCMD, g_qeglobals.d_hwndMain, AddCommandDlgProc);
				DialogBox(g_qeglobals.d_hInstance, (char *)IDD_ADDCMD, hwndDlg, AddCommandDlgProc);
				UpdateBSPCommandList (hwndDlg);
				break;

			case IDC_EDITCMD:
//				DialogBox(g_qeglobals.d_hInstance, (char *)IDD_ADDCMD, g_qeglobals.d_hwndMain, EditCommandDlgProc);
				DialogBox(g_qeglobals.d_hInstance, (char *)IDD_ADDCMD, hwndDlg, EditCommandDlgProc);
				UpdateBSPCommandList (hwndDlg);
				break;

			case IDC_REMCMD:
				index = SendDlgItemMessage (hwndDlg, IDC_CMD_LIST, LB_GETCURSEL, 0, 0);
				SendDlgItemMessage(hwndDlg, IDC_CMD_LIST, LB_GETTEXT, index, (LPARAM) (LPCTSTR) key);
				DeleteKey (g_qeglobals.d_project_entity, key);
				common->Printf ("Selected %d\n", index);
				UpdateBSPCommandList (hwndDlg);
				break;

			case IDOK:
				GetDlgItemText(hwndDlg, IDC_PRJBASEPATH, value, 1024);
				SetKeyValue (g_qeglobals.d_project_entity, "basepath", value);
				GetDlgItemText(hwndDlg, IDC_PRJMAPSPATH, value, 1024);
				SetKeyValue (g_qeglobals.d_project_entity, "mapspath", value);
				GetDlgItemText(hwndDlg, IDC_PRJRSHCMD, value, 1024);
				SetKeyValue (g_qeglobals.d_project_entity, "rshcmd", value);
				GetDlgItemText(hwndDlg, IDC_PRJREMOTEBASE, value, 1024);
				SetKeyValue (g_qeglobals.d_project_entity, "remotebasepath", value);
				GetDlgItemText(hwndDlg, IDC_PRJENTITYPATH, value, 1024);
				SetKeyValue (g_qeglobals.d_project_entity, "entitypath", value);
				GetDlgItemText(hwndDlg, IDC_PRJTEXPATH, value, 1024);
				SetKeyValue (g_qeglobals.d_project_entity, "texturepath", value);
				// Timo
				// read additional fields
				if ( IsDlgButtonChecked( hwndDlg, IDC_CHECK_BPRIMIT ) )
				{
					g_qeglobals.m_bBrushPrimitMode = TRUE;
				}
				else
				{
					g_qeglobals.m_bBrushPrimitMode = FALSE;
				}
				SetKeyValue ( g_qeglobals.d_project_entity, "brush_primit", ( g_qeglobals.m_bBrushPrimitMode ? "1" : "0" ) );

				EndDialog(hwndDlg, 1);
				QE_SaveProject(g_strProject);
				return TRUE;

			case IDCANCEL:
				EndDialog(hwndDlg, 0);
				return TRUE;
		}
	}
	return FALSE;
}
예제 #24
0
void Eclass_Init(){
	GSList *pFiles;

	// start by creating the default unknown eclass
	eclass_bad = EClass_Create( "UNKNOWN_CLASS", 0, 0.5, 0,NULL,NULL,NULL );

	// now scan the definitions
	_EClassTable *pTable = &g_EClassDefTable;
	while ( pTable )
	{
		// read in all scripts/*.<extension>
		pFiles = vfsGetFileList( "scripts", pTable->m_pfnGetExtension() );
		if ( pFiles ) {
			GSList *pFile = pFiles;
			while ( pFile )
			{
				/*!
				   \todo the MP/SP filtering rules need to be CLEANED UP and SANITIZED
				 */
				// HACK
				// JKII SP/MP mapping mode
				if ( g_pGameDescription->mGameFile == "jk2.game" || g_pGameDescription->mGameFile == "ja.game" ) {
					if ( !strcmp( ValueForKey( g_qeglobals.d_project_entity, "gamemode" ), "sp" ) ) {
						// SP mapping, ignore mp_*.def
						char *name = (char *)pFile->data;
						if ( name[0] == 'm' && name[1] == 'p' && name[2] == '_' ) {
							Sys_Printf( "Single Player mapping mode. Ignoring '%s'\n", name );
							pFile = pFile->next;
							continue;
						}
					}
					else
					{
						// MP mapping, ignore sp_*.def
						char *name = (char *)pFile->data;
						if ( name[0] == 's' && name[1] == 'p' && name[2] == '_' ) {
							Sys_Printf( "Multiplayer mapping mode. Ignoring '%s'\n", name );
							pFile = pFile->next;
							continue;
						}
					}
				}
				// RIANT
				// STVEF SP/MP mapping mode
				else if ( g_pGameDescription->mGameFile == "stvef.game" ) {
					if ( !strcmp( ValueForKey( g_qeglobals.d_project_entity, "gamemode" ), "sp" ) ) {
						// SP mapping, ignore mp_*.def
						char *name = (char *)pFile->data;
						if ( name[0] == 'm' && name[1] == 'p' && name[2] == '_' 
							|| name[0] == 'h' && name[1] == 'm' && name[2] == '_' ) {
							Sys_Printf( "Single Player mapping mode. Ignoring '%s'\n", name );
							pFile = pFile->next;
							continue;
						}
					}
					else
					{
						// HM mapping, ignore sp_*.def
						char *name = (char *)pFile->data;
						if ( name[0] == 's' && name[1] == 'p' && name[2] == '_' ) {
							Sys_Printf( "HoloMatch mapping mode. Ignoring '%s'\n", name );
							pFile = pFile->next;
							continue;
						}
					}
				}
				// for a given name, we grab the first .def in the vfs
				// this allows to override baseq3/scripts/entities.def for instance
				char relPath[PATH_MAX];
				strcpy( relPath, "scripts/" );
				strcat( relPath, (char*)pFile->data );
				char *fullpath = vfsGetFullPath( relPath, 0, 0 );
				if ( !fullpath ) {
					Sys_FPrintf( SYS_ERR, "Failed to find the full path for \"%s\" in the VFS\n", relPath );
				}
				else{
					pTable->m_pfnScanFile( fullpath );
				}
				if ( g_pGameDescription->mEClassSingleLoad ) {
					break;
				}
				pFile = pFile->next;
			}
			vfsClearFileDirList( &pFiles );
			pFiles = NULL;
		}
		else{
			Sys_FPrintf( SYS_ERR, "Didn't find any scripts/*.%s files to load EClass information\n", pTable->m_pfnGetExtension() );
		}

		// we deal with two formats max, if the other table exists, loop again
		if ( g_bHaveEClassExt && pTable == &g_EClassDefTable ) {
			pTable = &g_EClassExtTable;
		}
		else{
			pTable = NULL; // done, exit
		}
	}
	Eclass_CreateSpriteModelPaths();
}
예제 #25
0
void SetLightStyles( void )
{
	int			i, j, style, numStyles;
	qboolean	keepLights;
	const char	*t;
	entity_t	*e;
	epair_t		*ep, *next;
	char		value[ 10 ];
	char		lightTargets[ MAX_SWITCHED_LIGHTS ][ 64 ];
	int			lightStyles[ MAX_SWITCHED_LIGHTS ];
	
	
	/* ydnar: determine if we keep lights in the bsp */
	t = ValueForKey( &entities[ 0 ], "_keepLights" );
	keepLights = (t[ 0 ] == '1') ? qtrue : qfalse;
	
	/* any light that is controlled (has a targetname) must have a unique style number generated for it */
	numStyles = 0;
	for( i = 1; i < numEntities; i++ )
	{
		e = &entities[ i ];

		t = ValueForKey( e, "classname" );
		if( Q_strncasecmp( t, "light", 5 ) )
			continue;
		t = ValueForKey( e, "targetname" );
		if( t[ 0 ] == '\0' )
		{
			/* ydnar: strip the light from the BSP file */
			if( keepLights == qfalse )
			{
				ep = e->epairs;
				while( ep != NULL )
				{
					next = ep->next;
					free( ep->key );
					free( ep->value );
					free( ep );
					ep = next;
				}
				e->epairs = NULL;
				numStrippedLights++;
			}
			
			/* next light */
			continue;
		}
		
		/* get existing style */
		style = IntForKey( e, "style" );
		if( style < LS_NORMAL || style > LS_NONE )
			Error( "Invalid lightstyle (%d) on entity %d", style, i );
		
		/* find this targetname */
		for( j = 0; j < numStyles; j++ )
			if( lightStyles[ j ] == style && !strcmp( lightTargets[ j ], t ) )
				break;
		
		/* add a new style */
		if( j >= numStyles )
		{
			if( numStyles == MAX_SWITCHED_LIGHTS )
				Error( "MAX_SWITCHED_LIGHTS (%d) exceeded, reduce the number of lights with targetnames", MAX_SWITCHED_LIGHTS );
			strcpy( lightTargets[ j ], t );
			lightStyles[ j ] = style;
			numStyles++;
		}
		
		/* set explicit style */
		sprintf( value, "%d", 32 + j );
		SetKeyValue( e, "style", value );
		
		/* set old style */
		if( style != LS_NORMAL )
		{
			sprintf( value, "%d", style );
			SetKeyValue( e, "switch_style", value );
		}
	}
	
	/* emit some statistics */
	Sys_FPrintf( SYS_VRB, "%9d light entities stripped\n", numStrippedLights );
}
예제 #26
0
/*
=================
ParseMapEntity

parses a single entity out of a map file
=================
*/
static bool ParseMapEntity( bool onlyLights )
{
	epair_t		*ep;
	token_t		token;
	const char	*classname, *value;
	float		lightmapScale;
	char		shader[ MAX_SHADERPATH ];
	shaderInfo_t	*celShader = NULL;
	brush_t		*brush;
	parseMesh_t	*patch;
	bool		funcGroup;
	int		castShadows, recvShadows;
	static bool	map_type = false;

	if( !Com_ReadToken( mapfile, SC_ALLOW_NEWLINES|SC_COMMENT_SEMICOLON, &token ))
		return false; // end of .map file
	if( com.stricmp( token.string, "{" ))  Sys_Break( "ParseEntity: found %s instead {\n", token.string );
	if( numEntities >= MAX_MAP_ENTITIES ) Sys_Break( "MAX_MAP_ENTITIES limit exceeded\n" );	

	entitySourceBrushes = 0;
	mapEnt = &entities[numEntities];
	numEntities++;
	memset( mapEnt, 0, sizeof( *mapEnt ));
	
	mapEnt->mapEntityNum = numMapEntities;
	numMapEntities++;
	
	while( 1 )
	{
		if( !Com_ReadToken( mapfile, SC_ALLOW_NEWLINES|SC_COMMENT_SEMICOLON, &token ))
			Sys_Break( "ParseEntity: EOF without closing brace\n" );

		if( !com.stricmp( token.string, "}" )) break;
		if( !com.stricmp( token.string, "{" ))
		{
			// parse a brush or patch
			if( !Com_ReadToken( mapfile, SC_ALLOW_NEWLINES, &token )) break;
			
			if( !com.stricmp( token.string, "patchDef2" ))
			{
				numMapPatches++;
				ParsePatch( onlyLights );
				g_bBrushPrimit = BRUSH_RADIANT;
			}
			else if( !com.stricmp( token.string, "terrainDef" ))
			{
				MsgDev( D_WARN, "Terrain entity parsing not supported in this build.\n" );
				Com_SkipBracedSection( mapfile, 0 );
				g_bBrushPrimit = BRUSH_RADIANT;
			}
			else if( !com.stricmp( token.string, "brushDef" ))
			{
				// parse brush primitive
				g_bBrushPrimit = BRUSH_RADIANT;
				ParseBrush( onlyLights );
			}
			else
			{
				if( g_bBrushPrimit == BRUSH_RADIANT )
					Sys_Break( "mixed brush primitive with another format\n" );
				if( g_bBrushPrimit == BRUSH_UNKNOWN ) g_bBrushPrimit = BRUSH_WORLDCRAFT_21;
				
				// QuArK or WorldCraft map (unknown at this point)
				Com_SaveToken( mapfile, &token );
				ParseBrush( onlyLights );
			}
			entitySourceBrushes++;
		}
		else
		{
			// parse a key / value pair
			ep = ParseEpair( mapfile, &token );

			if( !com.strcmp( ep->key, "mapversion" ))
			{
				if( com.atoi( ep->value ) == VALVE_FORMAT )
				{
					Msg( "Valve Format Map detected\n" );
					g_bBrushPrimit = BRUSH_WORLDCRAFT_22;
				}
				else if( com.atoi( ep->value ) == GEARBOX_FORMAT )
				{
					Msg( "Gearcraft Format Map detected\n" );
					g_bBrushPrimit = BRUSH_GEARCRAFT_40;
				}
				else g_bBrushPrimit = BRUSH_WORLDCRAFT_21;
			}
			if( ep->key[0] != '\0' && ep->value[0] != '\0' )
			{
				ep->next = mapEnt->epairs;
				mapEnt->epairs = ep;
			}
		}
	}

	if( !map_type && g_bBrushPrimit != BRUSH_UNKNOWN )
	{
		MAPTYPE();
		map_type = true;
	}
	
	classname = ValueForKey( mapEnt, "classname" );
	
	if( onlyLights && com.strnicmp( classname, "light", 5 ))
	{
		numEntities--;
		return true;
	}
	
	if( !com.stricmp( "func_group", classname ))
		funcGroup = true;
	else funcGroup = false;
	
	// worldspawn (and func_groups) default to cast/recv shadows in worldspawn group
	if( funcGroup || mapEnt->mapEntityNum == 0 )
	{
		castShadows = WORLDSPAWN_CAST_SHADOWS;
		recvShadows = WORLDSPAWN_RECV_SHADOWS;
	}
	else // other entities don't cast any shadows, but recv worldspawn shadows
	{
		castShadows = ENTITY_CAST_SHADOWS;
		recvShadows = ENTITY_RECV_SHADOWS;
	}
	
	// get explicit shadow flags
	GetEntityShadowFlags( mapEnt, NULL, &castShadows, &recvShadows );
	
	// get lightmap scaling value for this entity
	if( com.strcmp( "", ValueForKey( mapEnt, "lightmapscale" )) || com.strcmp( "", ValueForKey( mapEnt, "_lightmapscale" )))
	{
		// get lightmap scale from entity
		lightmapScale = FloatForKey( mapEnt, "lightmapscale" );
		if( lightmapScale <= 0.0f ) lightmapScale = FloatForKey( mapEnt, "_lightmapscale" );
		if( lightmapScale > 0.0f ) Msg( "Entity %d (%s) has lightmap scale of %.4f\n", mapEnt->mapEntityNum, classname, lightmapScale );
	}
	else lightmapScale = 0.0f;
	
	// get cel shader :) for this entity
	value = ValueForKey( mapEnt, "_celshader" );
	if( value[0] == '\0' ) value = ValueForKey( &entities[0], "_celshader" );
	if( value[0] != '\0' )
	{
		com.snprintf( shader, sizeof( shader ), "textures/%s", value );
		celShader = ShaderInfoForShader( shader );
		Msg( "Entity %d (%s) has cel shader %s\n", mapEnt->mapEntityNum, classname, celShader->shader );
	}
	else celShader = NULL;
	
	// attach stuff to everything in the entity
	for( brush = mapEnt->brushes; brush != NULL; brush = brush->next )
	{
		brush->entityNum = mapEnt->mapEntityNum;
		brush->castShadows = castShadows;
		brush->recvShadows = recvShadows;
		brush->lightmapScale = lightmapScale;
		brush->celShader = celShader;
	}
	
	for( patch = mapEnt->patches; patch != NULL; patch = patch->next )
	{
		patch->entityNum = mapEnt->mapEntityNum;
		patch->castShadows = castShadows;
		patch->recvShadows = recvShadows;
		patch->lightmapScale = lightmapScale;
		patch->celShader = celShader;
	}
	
	SetEntityBounds( mapEnt );
	
	// load shader index map (equivalent to old terrain alphamap)
	LoadEntityIndexMap( mapEnt );
	
	// get entity origin and adjust brushes
	GetVectorForKey( mapEnt, "origin", mapEnt->origin );
	if( mapEnt->origin[0] || mapEnt->origin[1] || mapEnt->origin[2] )
		AdjustBrushesForOrigin( mapEnt );

	// group_info entities are just for editor grouping
	if( !com.stricmp( "group_info", classname ))
	{
		numEntities--;
		return true;
	}
	
	// group entities are just for editor convenience, toss all brushes into worldspawn
	if( funcGroup )
	{
		MoveBrushesToWorld( mapEnt );
		numEntities--;
		return true;
	}
	return true;
}
예제 #27
0
파일: convert_ase.c 프로젝트: otty/cake3
int WriteASEFile(char *filename)
{
	int             i, j, s, modelNum;
	FILE           *f;
	dshader_t      *shader;
	dmodel_t       *dm;
	drawSurface_t  *ds;
	entity_t       *e;
	vec3_t          origin;
	const char     *key;
	char            name[1024], base[1024];

	Sys_Printf("writing %s\n", filename);
	f = fopen(filename, "wb");
	if(!f)
		Error("Can't write %s\b", filename);

	// print header
	fprintf(f, "*3DSMAX_ASCIIEXPORT\t200\r\n");
	fprintf(f, "*COMMENT\t\"Generated by XMap (XreaL) -bsp2ase\"\r\n");
	fprintf(f, "*SCENE\t{\r\n");
	fprintf(f, "\t*SCENE_FILENAME\t\"%s\"\r\n", base);
	fprintf(f, "\t*SCENE_FIRSTFRAME\t0\r\n");
	fprintf(f, "\t*SCENE_LASTFRAME\t100\r\n");
	fprintf(f, "\t*SCENE_FRAMESPEED\t30\r\n");
	fprintf(f, "\t*SCENE_TICKSPERFRAME\t160\r\n");
	fprintf(f, "\t*SCENE_BACKGROUND_STATIC\t0.0000\t0.0000\t0.0000\r\n");
	fprintf(f, "\t*SCENE_AMBIENT_STATIC\t0.0000\t0.0000\t0.0000\r\n");
	fprintf(f, "}\r\n");

	// print materials
	fprintf(f, "*MATERIAL_LIST\t{\r\n");
	fprintf(f, "\t*MATERIAL_COUNT\t%d\r\n", numShaders);
	for(i = 0; i < numShaders; i++)
	{
		shader = &dshaders[i];
		ConvertShader(f, shader, i);
	}
	fprintf(f, "}\r\n");

	// walk entity list
	for(i = 0; i < numEntities; i++)
	{
		// get entity and model
		e = &entities[i];
		if(i == 0)
		{
			modelNum = 0;
		}
		else
		{
			key = ValueForKey(e, "model");
			if(key[0] != '*')
			{
				continue;
			}
			modelNum = atoi(key + 1);
		}
		dm = &dmodels[modelNum];

		// get entity origin
		key = ValueForKey(e, "origin");
		if(key[0] == '\0')
			VectorClear(origin);
		else
			GetVectorForKey(e, "origin", origin);

		// convert model
		for(j = 0; j < dm->numSurfaces; j++)
		{
			s = j + dm->firstSurface;
			ds = &drawSurfaces[s];

			ConvertSurface(f, dm, modelNum, ds, s, origin);
		}
	}

	// close the file
	fclose(f);

	// return to sender
	return 0;
}
예제 #28
0
/*
=============
FloodEntities

Marks all nodes that can be reached by entites
=============
*/
qboolean FloodEntities (tree_t *tree)
{
	int		i;
	Vector	origin;
	char	*cl;
	qboolean	inside;
	node_t *headnode;

	headnode = tree->headnode;
	qprintf ("--- FloodEntities ---\n");
	inside = false;
	tree->outside_node.occupied = 0;

	for (i=1 ; i<num_entities ; i++)
	{
		GetVectorForKey (&entities[i], "origin", origin);
		if (VectorCompare(origin, vec3_origin))
			continue;

		cl = ValueForKey (&entities[i], "classname");

		origin[2] += 1;	// so objects on floor are ok

		// nudge playerstart around if needed so clipping hulls allways
		// have a valid point
		if (!strcmp (cl, "info_player_start"))
		{
			int	x, y;

			for (x=-16 ; x<=16 ; x += 16)
			{
				for (y=-16 ; y<=16 ; y += 16)
				{
					origin[0] += x;
					origin[1] += y;
					if (PlaceOccupant (headnode, origin, &entities[i]))
					{
						inside = true;
						goto gotit;
					}
					origin[0] -= x;
					origin[1] -= y;
				}
			}
gotit: ;
		}
		else
		{
			if (PlaceOccupant (headnode, origin, &entities[i]))
				inside = true;
		}
	}

	if (!inside)
	{
		qprintf ("no entities in open -- no filling\n");
	}

	if (tree->outside_node.occupied)
	{
		qprintf ("entity reached from outside -- no filling\n" );
	}

	return (qboolean)(inside && !tree->outside_node.occupied);
}
예제 #29
0
/*
=================
LoadEntityIndexMap

based on LoadAlphaMap() from terrain.c, a little more generic
=================
*/
void LoadEntityIndexMap( entity_t *e )
{
	int		i, size, numLayers;
	const char	*value, *indexMapFilename, *shader;
	char		offset[ 4096 ], *search, *space;
	rgbdata_t		*image;
	byte		*pixels;
	uint		*pixels32;
	indexMap_t	*im;
	brush_t		*b;
	parseMesh_t	*p;
	
	
	if( e->brushes == NULL && e->patches == NULL )
		return;
	
	value = ValueForKey( e, "_indexmap" );
	if( value[0] == '\0' ) value = ValueForKey( e, "alphamap" );
	if( value[0] == '\0' ) return;
	indexMapFilename = value;
	
	// get number of layers (support legacy "layers" key as well)
	value = ValueForKey( e, "_layers" );
	if( value[0] == '\0' ) value = ValueForKey( e, "layers" );
	if( value[0] == '\0' )
	{
		Msg( "Warning: Entity with index/alpha map \"%s\" has missing \"_layers\" or \"layers\" key\n", indexMapFilename );
		Msg( "Entity will not be textured properly. Check your keys/values.\n" );
		return;
	}
	numLayers = com.atoi( value );
	if( numLayers < 1 )
	{
		Msg( "Warning: Entity with index/alpha map \"%s\" has < 1 layer (%d)\n", indexMapFilename, numLayers );
		Msg( "Entity will not be textured properly. Check your keys/values.\n" );
		return;
	}
	
	// get base shader name (support legacy "shader" key as well)
	value = ValueForKey( mapEnt, "_shader" );
	if( value[0] == '\0' ) value = ValueForKey( e, "shader" );
	if( value[0] == '\0' )
	{
		Msg( "Warning: Entity with index/alpha map \"%s\" has missing \"_shader\" or \"shader\" key\n", indexMapFilename );
		Msg( "Entity will not be textured properly. Check your keys/values.\n" );
		return;
	}
	shader = value;
	
	MsgDev( D_NOTE, "Entity %d (%s) has shader index map \"%s\"\n",  mapEnt->mapEntityNum, ValueForKey( e, "classname" ), indexMapFilename );

	image = FS_LoadImage( indexMapFilename, NULL, 0 );
	if( !image ) return;

	Image_Process( &image, 0, 0, IMAGE_FORCE_RGBA );
	
	size = image->width * image->height;
	pixels = Malloc( size );
	pixels32 = (uint *)image->buffer;

	for( i = 0; i < size; i++ )
	{
		pixels[i] = ((pixels32[i] & 0xFF) * numLayers) / 256;
		if( pixels[i] >= numLayers ) pixels[i] = numLayers - 1;
	}

	// the index map must be at least 2x2 pixels
	if( image->width < 2 || image->height < 2 )
	{
		Msg( "Warning: Entity with index/alpha map \"%s\" is smaller than 2x2 pixels\n", indexMapFilename );
		Msg( "Entity will not be textured properly. Check your keys/values.\n" );
		FS_FreeImage( image );
		return;
	}

	// create a new index map
	im = Malloc( sizeof( *im ));
	im->w = image->width;
	im->h = image->height;
	im->numLayers = numLayers;
	com.strncpy( im->name, indexMapFilename, sizeof( im->name ));
	com.strncpy( im->shader, shader, sizeof( im->shader ));
	im->pixels = pixels;
	
	value = ValueForKey( mapEnt, "_offsets" );
	if( value[0] == '\0' ) value = ValueForKey( e, "offsets" );
	if( value[0] != '\0' )
	{
		// value is a space-seperated set of numbers
		com.strncpy( offset, value, sizeof( offset ));
		search = offset;
		
		for( i = 0; i < 256 && *search != '\0'; i++ )
		{
			space = com.strstr( search, " " );
			if( space != NULL ) *space = '\0';
			im->offsets[i] = com.atof( search );
			if( space == NULL ) break;
			search = space + 1;
		}
	}
	
	// store the index map in every brush/patch in the entity
	for( b = e->brushes; b != NULL; b = b->next ) b->im = im;
	for( p = e->patches; p != NULL; p = p->next ) p->im = im;

	FS_FreeImage( image );
}
예제 #30
0
qtexture_t* WINAPI QERApp_Try_Texture_ForName(const char* name)
{
	qtexture_t *q;
	char f1[1024],f2[1024];
	unsigned char *pPixels = NULL;
	int nWidth,nHeight;

  // convert the texture name to the standard format we use in qtexture_t
  char *stdName = CleanTextureName(name);

  // use the hash table
  q = NULL;
  g_qeglobals.d_qtexmap->Lookup( stdName, (void *&)q );
  if (q)
    return q;
#ifdef QTEXMAP_DEBUG
  for (q=g_qeglobals.d_qtextures ; q ; q=q->next)
	{
		if (!strcmp(stdName,  q->name))
    {
      Sys_Printf("ERROR: %s is not in texture map, but was found in texture list\n");
			return q;
    }
	}
#endif
#if 0
  for (q=g_qeglobals.d_qtextures ; q ; q=q->next)
	{
		if (!strcmp(stdName,  q->name))
				return q;
	}
#endif
	//++timo TODO: say something about loading the file?
	// try loading the texture
	//++timo FIXME: "texturepath" is no use now?
	sprintf(f1, "%s/%s", ValueForKey (g_qeglobals.d_project_entity, "basepath"), name);
	QE_ConvertDOSToUnixName( f2, f1 );
	// NOTE: we may need a global strategy to support default extensions etc.
	strcpy(f1,f2);
	// check wether a filename extension was provided
	// NOTE: only works for 3 letters extensions ( .tga .jpg ... )
	if (f1[strlen(f1)-4] == '.')
	{
		// try straight loading
		LoadImage( f1, &pPixels, &nWidth, &nHeight );
	}
	if (!pPixels)
	{
		// try adding extensions, .tga first
		sprintf(f2,"%s.tga",f1);
		LoadImage( f2, &pPixels, &nWidth, &nHeight );
		if (!pPixels)
		{
			// .jpg
			sprintf(f2,"%s.jpg",f1);
			LoadImage( f2, &pPixels, &nWidth, &nHeight );
		}
	}
	if (!pPixels)
		// we failed
		return NULL;
	else
	{
		// TODO: display .pk3 file name if loaded from .pk3 (needs to write a VFS .. sort of)
		Sys_Printf("LOADED: %s\n", f2 );
	}
	// instanciate a new qtexture_t
	// NOTE: when called by a plugin we must make sure we have set Radiant's GL context before binding the texture

	// we'll be binding the GL texture now
	// need to check we are using a right GL context
	// with GL plugins that have their own window, the GL context may be the plugin's, in which case loading textures will bug
	HDC currentHDC = qwglGetCurrentDC();
	HGLRC currentHGLRC = qwglGetCurrentContext();
	//++timo FIXME: this may duplicate with qtexture_t* WINAPI QERApp_Texture_ForName (const char *name)
	//++timo FIXME: we need a list of lawfull GL contexts or something?
	// I'd rather always use the same GL context for binding...
	if (currentHDC != g_qeglobals.d_hdcBase || currentHGLRC != g_qeglobals.d_hglrcBase)
	{
#ifdef _DEBUG
		Sys_Printf("Switching context!\n");
#endif
		qwglMakeCurrent( g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase );
	}

	//++timo TODO: remove that and use our own implementation?
	q = Texture_LoadTGATexture( pPixels, nWidth, nHeight, NULL, 0, 0, 0);
	free(pPixels);
	// fill qtexture_t information
	//++timo FIXME: filename will be removed .. name for qtexture_t is actually the filename now
  // NOTE: see qtexture_s::name for naming conventions, must remove filename extension
	strcpy( q->filename, name );
	strcpy( q->name, name );
	// only strip extension if extension there is!
	if (q->name[strlen(q->name)-4] == '.')
		q->name[strlen(q->name)-4]='\0';
	// hook into the main qtexture_t list
	q->next = g_qeglobals.d_qtextures;
	g_qeglobals.d_qtextures = q;
  // push it in the map
  g_qeglobals.d_qtexmap->SetAt( q->name, q );

	return q;
}