コード例 #1
0
/*
================
CPathTreeCtrl::AddPathToTree

Adds a new item to the tree.
Assumes new paths after the current stack path do not yet exist.
================
*/
HTREEITEM CPathTreeCtrl::AddPathToTree( const idStr &pathName, const int id, idPathTreeStack &stack ) {
	int lastSlash;
	idStr itemName, tmpPath;
	HTREEITEM item;

	lastSlash = pathName.Last( '/' );

	while( stack.Num() > 1 ) {
		if ( pathName.Icmpn( stack.TopName(), stack.TopNameLength() ) == 0 ) {
			break;
		}
		stack.Pop();
	}

	while( lastSlash > stack.TopNameLength() ) {
		pathName.Mid( stack.TopNameLength(), pathName.Length(), tmpPath );
		tmpPath.Left( tmpPath.Find( '/' ), itemName );
		item = InsertItem( itemName, stack.TopItem() );
		stack.Push( item, itemName );
	}

	pathName.Mid( stack.TopNameLength(), pathName.Length(), itemName );
	item = InsertItem( itemName, stack.TopItem() );
	SetItemData( item, id );

	return item;
}
コード例 #2
0
/*
================
CPathTreeCtrl::InsertPathIntoTree

Inserts a new item going from the root down the tree only creating paths where necessary.
This is slow and should only be used to insert single items.
================
*/
HTREEITEM CPathTreeCtrl::InsertPathIntoTree( const idStr &pathName, const int id ) {
	int lastSlash;
	idStr path, tmpPath, itemName;
	HTREEITEM item, parentItem;

	parentItem = NULL;
	item = GetRootItem();

	lastSlash = pathName.Last( '/' );

	while( item && lastSlash > path.Length() ) {
		itemName = GetItemText( item );
		tmpPath = path + itemName;
		if ( pathName.Icmpn( tmpPath, tmpPath.Length() ) == 0 ) {
			parentItem = item;
			item = GetChildItem( item );
			path = tmpPath + "/";
		} else {
			item = GetNextSiblingItem( item );
		}
	}

	while( lastSlash > path.Length() ) {
		pathName.Mid( path.Length(), pathName.Length(), tmpPath );
		tmpPath.Left( tmpPath.Find( '/' ), itemName );
		parentItem = InsertItem( itemName, parentItem );
		path += itemName + "/";
	}

	pathName.Mid( path.Length(), pathName.Length(), itemName );
	item = InsertItem( itemName, parentItem, TVI_SORT );
	SetItemData( item, id );

	return item;
}
コード例 #3
0
ファイル: Lexer.cpp プロジェクト: c4tnt/DLR
/*
================
idLexer::GetLastWhiteSpace
================
*/
int idLexer::GetLastWhiteSpace( idStr &whiteSpace ) const {
	whiteSpace.Clear();
	for ( const char *p = whiteSpaceStart_p; p < whiteSpaceEnd_p; p++ ) {
		whiteSpace.Append( *p );
	}
	return whiteSpace.Length();
}
コード例 #4
0
ファイル: ModInfo.cpp プロジェクト: jaredmitch/executable
void CModInfo::GetMissionTitles(idStr missionTitles)
{
	if (modName.IsEmpty())
	{
		return;
	}

	int startIndex = 0;
	idStr start = "Mission 1 Title: ";
	idStr end   = "Mission 2 Title: ";
	int endIndex = missionTitles.Find(end.c_str(), true); // grayman #3733
	bool finished = false;
	for ( int i = 1 ; ; i++ )
	{
		idStr title = idStr(missionTitles, startIndex, endIndex); // grayman #3733
		Strip(start.c_str(), title);
		_missionTitles.Append(title);
		start = end;
		startIndex = endIndex;
		if (finished)
		{
			break;
		}
		end = va("Mission %d Title: ",i+2);
		endIndex = missionTitles.Find(end.c_str(), true, startIndex); // grayman #3733
		if (endIndex < 0)
		{
			endIndex = missionTitles.Length();
			finished = true;
		}
	}
}
コード例 #5
0
/*
================
idTypeInfoTools::ParseTemplateArguments
================
*/
bool idTypeInfoTools::ParseTemplateArguments( idLexer &src, idStr &arguments ) {
	int indent;
	idToken token;

	arguments = "";

	if ( !src.ExpectTokenString( "<" ) ) {
		return false;
	}

	indent = 1;
	while( indent ) {
		if ( !src.ReadToken( &token ) ) {
			break;
		}
		if ( token == "<" ) {
			indent++;
		} else if ( token == ">" ) {
			indent--;
		} else {
			if ( arguments.Length() ) {
				arguments += " ";
			}
			arguments += token;
		}
	}
	return true;
}
コード例 #6
0
/*
================
DialogDeclEditor::TestDecl
================
*/
bool DialogDeclEditor::TestDecl(const idStr &declText)
{
	idLexer src(LEXFL_NOSTRINGCONCAT);
	idToken token;
	int indent;

	src.LoadMemory(declText, declText.Length(), "decl text");

	indent = 0;

	while (src.ReadToken(&token)) {
		if (token == "{") {
			indent++;
		} else if (token == "}") {
			indent--;
		}
	}

	if (indent < 0) {
		MessageBox("Missing opening brace!", va("Error saving %s", decl->GetFileName()), MB_OK | MB_ICONERROR);
		return false;
	}

	if (indent > 0) {
		MessageBox("Missing closing brace!", va("Error saving %s", decl->GetFileName()), MB_OK | MB_ICONERROR);
		return false;
	}

	return true;
}
コード例 #7
0
ファイル: main.cpp プロジェクト: revelator/Revelation
/*
================
Sys_DefaultBasePath

Get the default base path
- binary image path
- current directory
- hardcoded
Try to be intelligent: if there is no BASE_GAMEDIR, try the next path
================
*/
const char *Sys_DefaultBasePath( void ) {
	struct stat st;
	idStr testbase;
	basepath = Sys_EXEPath();
	if( basepath.Length() ) {
		basepath.StripFilename();
		testbase = basepath;
		testbase += "/";
		testbase += BASE_GAMEDIR;
		if( stat( testbase.c_str(), &st ) != -1 && S_ISDIR( st.st_mode ) ) {
			return basepath.c_str();
		} else {
			common->Printf( "no '%s' directory in exe path %s, skipping\n", BASE_GAMEDIR, basepath.c_str() );
		}
	}
	if( basepath != Posix_Cwd() ) {
		basepath = Posix_Cwd();
		testbase = basepath;
		testbase += "/";
		testbase += BASE_GAMEDIR;
		if( stat( testbase.c_str(), &st ) != -1 && S_ISDIR( st.st_mode ) ) {
			return basepath.c_str();
		} else {
			common->Printf( "no '%s' directory in cwd path %s, skipping\n", BASE_GAMEDIR, basepath.c_str() );
		}
	}
	common->Printf( "WARNING: using hardcoded default base path\n" );
	return LINUX_DEFAULT_PATH;
}
コード例 #8
0
void idGLDrawableView::setCustomModel( const idStr modelName ) {

	if ( modelName.Length() ) {
		objectId = -1;
	} else {
		objectId = 0;
	}

	customModelName = modelName;

	UpdateModel();
}
コード例 #9
0
/*
============
idInternalCVar::Update
============
*/
void idInternalCVar::Update( const idCVar *cvar )
{

    // if this is a statically declared variable
    if ( cvar->GetFlags() & CVAR_STATIC )
    {

        if ( flags & CVAR_STATIC )
        {

            // the code has more than one static declaration of the same variable, make sure they have the same properties
            if ( resetString.Icmp( cvar->GetString() ) != 0 )
            {
                common->Warning( "CVar '%s' declared multiple times with different initial value", nameString.c_str() );
            }
            if ( ( flags & (CVAR_BOOL|CVAR_INTEGER|CVAR_FLOAT) ) != ( cvar->GetFlags() & (CVAR_BOOL|CVAR_INTEGER|CVAR_FLOAT) ) )
            {
                common->Warning( "CVar '%s' declared multiple times with different type", nameString.c_str() );
            }
            if ( valueMin != cvar->GetMinValue() || valueMax != cvar->GetMaxValue() )
            {
                common->Warning( "CVar '%s' declared multiple times with different minimum/maximum", nameString.c_str() );
            }

        }

        // the code is now specifying a variable that the user already set a value for, take the new value as the reset value
        resetString = cvar->GetString();
        descriptionString = cvar->GetDescription();
        description = descriptionString.c_str();
        valueMin = cvar->GetMinValue();
        valueMax = cvar->GetMaxValue();
        Mem_Free( valueStrings );
        valueStrings = CopyValueStrings( cvar->GetValueStrings() );
        valueCompletion = cvar->GetValueCompletion();
        UpdateValue();
        cvarSystem->SetModifiedFlags( cvar->GetFlags() );
    }

    flags |= cvar->GetFlags();

    UpdateCheat();

    // only allow one non-empty reset string without a warning
    if ( resetString.Length() == 0 )
    {
        resetString = cvar->GetString();
    }
    else if ( cvar->GetString()[0] && resetString.Cmp( cvar->GetString() ) != 0 )
    {
        common->Warning( "cvar \"%s\" given initial values: \"%s\" and \"%s\"\n", nameString.c_str(), resetString.c_str(), cvar->GetString() );
    }
}
コード例 #10
0
/*
==================
Sym_GetFuncInfo
==================
*/
void Sym_GetFuncInfo( long addr, idStr &module, idStr &funcName )
{
    MEMORY_BASIC_INFORMATION mbi;
    module_t *m;
    symbol_t *s;

    VirtualQuery( (void*)addr, &mbi, sizeof(mbi) );

    for ( m = modules; m != NULL; m = m->next )
    {
        if ( m->address == (int) mbi.AllocationBase )
        {
            break;
        }
    }
    if ( !m )
    {
        Sym_Init( addr );
        m = modules;
    }

    for ( s = m->symbols; s != NULL; s = s->next )
    {
        if ( s->address == addr )
        {

            char undName[MAX_STRING_CHARS];
            if ( UnDecorateSymbolName( s->name, undName, sizeof(undName), UNDECORATE_FLAGS ) )
            {
                funcName = undName;
            }
            else
            {
                funcName = s->name;
            }
            for ( int i = 0; i < funcName.Length(); i++ )
            {
                if ( funcName[i] == '(' )
                {
                    funcName.CapLength( i );
                    break;
                }
            }
            module = m->name;
            return;
        }
    }

    sprintf( funcName, "0x%08x", addr );
    module = "";
}
コード例 #11
0
void CConsoleDlg::ExecuteCommand ( const idStr& cmd ) {
	CString str;
	if ( cmd.Length() > 0 ) {
		str = cmd;
	}
	else {
		editInput.GetWindowText(str);
	}

	if ( str != "" ) {			
		editInput.SetWindowText("");
		common->Printf("%s\n", str.GetBuffer(0));		

		//avoid adding multiple identical commands in a row
		int index = consoleHistory.Num ();

		if ( index == 0 || str.GetBuffer(0) != consoleHistory[index-1]) {					
			//keep the history to 16 commands, removing the oldest command
			if ( consoleHistory.Num () > 16 ) {
				consoleHistory.RemoveIndex ( 0 );
			}
			currentHistoryPosition = consoleHistory.Append ( str.GetBuffer (0) );    
		}
		else {
			currentHistoryPosition = consoleHistory.Num () - 1;
		}

		currentCommand.Clear ();

		bool propogateCommand = true;

		//process some of our own special commands
		if ( str.CompareNoCase ( "clear" ) == 0) {
			editConsole.SetSel ( 0 , -1 );
			editConsole.Clear ();
		}
		else if ( str.CompareNoCase ( "edit" ) == 0) {
			propogateCommand = false;
		}
		if ( propogateCommand ) {
			cmdSystem->BufferCommandText( CMD_EXEC_NOW, str );
		}

		Sys_UpdateWindows(W_ALL);
	}
}
コード例 #12
0
TimerValue CStimResponseTimer::ParseTimeString( idStr &str ) {
	TimerValue v;
	int h, m, s, ms;
	idStr source = str;
	v.Time.Flags = TIMER_UNDEFINED;
	if( str.Length() == 0 ) {
		goto Quit;
	}
	h = m = s = ms = 0;
	// Get the first few characters that define the hours
	h = atoi( source.Left( source.Find( ":" ) ).c_str() );
	// Strip the first few numbers plus the colon from the source string
	source = source.Right( source.Length() - source.Find( ":" ) - 1 );
	// Parse the minutes
	m = atoi( source.Left( source.Find( ":" ) ).c_str() );
	if( !( m >= 0 && m <= 59 ) ) {
		DM_LOG( LC_STIM_RESPONSE, LT_ERROR )LOGSTRING( "Invalid minute string [%s]\r", str.c_str() );
		goto Quit;
	}
	// Strip the first few numbers plus the colon from the source string
	source = source.Right( source.Length() - source.Find( ":" ) - 1 );
	// Parse the seconds
	s = atoi( source.Left( source.Find( ":" ) ).c_str() );
	if( !( s >= 0 && s <= 59 ) ) {
		DM_LOG( LC_STIM_RESPONSE, LT_ERROR )LOGSTRING( "Invalid second string [%s]\r", str.c_str() );
		goto Quit;
	}
	// Parse the milliseconds, this is the remaining part of the string
	ms = atoi( source.Right( source.Length() - source.Find( ":" ) - 1 ).c_str() );
	if( !( ms >= 0 && ms <= 999 ) ) {
		DM_LOG( LC_STIM_RESPONSE, LT_ERROR )LOGSTRING( "Invalid millisecond string [%s]\r", str.c_str() );
		goto Quit;
	}
	DM_LOG( LC_STIM_RESPONSE, LT_DEBUG )LOGSTRING( "Parsed timer string: [%s] to %d:%d:%d:%d\r", str.c_str(), h, m, s, ms );
	v.Time.Hour = h;
	v.Time.Minute = m;
	v.Time.Second = s;
	v.Time.Millisecond = ms;
Quit:
	return v;
}
コード例 #13
0
ファイル: MaterialDoc.cpp プロジェクト: Deepfreeze32/taken
/**
* Applies any source changes to the edit representation of the material.
*/
void MaterialDoc::ApplySourceModify(idStr& text) {
	
	if(sourceModify) {
		
		//Changes in the source need to clear any undo redo buffer because we have no idea what has changed
		manager->ClearUndo();
		manager->ClearRedo();

		ClearEditMaterial();

		idLexer		src;
		src.LoadMemory(text, text.Length(), "Material");

		src.SetFlags( 
			LEXFL_NOSTRINGCONCAT |			// multiple strings seperated by whitespaces are not concatenated
			LEXFL_NOSTRINGESCAPECHARS |		// no escape characters inside strings
			LEXFL_ALLOWPATHNAMES |			// allow path seperators in names
			LEXFL_ALLOWMULTICHARLITERALS |	// allow multi character literals
			LEXFL_ALLOWBACKSLASHSTRINGCONCAT |	// allow multiple strings seperated by '\' to be concatenated
			LEXFL_NOFATALERRORS				// just set a flag instead of fatal erroring
			);

		idToken token;
		if(!src.ReadToken(&token)) {
			src.Warning( "Missing decl name" );
			return;
		}
		
		ParseMaterial(&src);
		sourceModify = false;

		//Check to see if the name has changed
		if(token.Icmp(name)) {
			SetMaterialName(token, false);
		}
	}
}
コード例 #14
0
ファイル: CVarSystem.cpp プロジェクト: AndreiBarsan/doom3.gpl
/*
============
idInternalCVar::UpdateValue
============
*/
void idInternalCVar::UpdateValue( void ) {
	bool clamped = false;

	if ( flags & CVAR_BOOL ) {
		integerValue = ( atoi( value ) != 0 );
		floatValue = integerValue;
		if ( idStr::Icmp( value, "0" ) != 0 && idStr::Icmp( value, "1" ) != 0 ) {
			valueString = idStr( (bool)( integerValue != 0 ) );
			value = valueString.c_str();
		}
	} else if ( flags & CVAR_INTEGER ) {
		integerValue = (int)atoi( value );
		if ( valueMin < valueMax ) {
			if ( integerValue < valueMin ) {
				integerValue = (int)valueMin;
				clamped = true;
			} else if ( integerValue > valueMax ) {
				integerValue = (int)valueMax;
				clamped = true;
			}
		}
		if ( clamped || !idStr::IsNumeric( value ) || idStr::FindChar( value, '.' ) ) {
			valueString = idStr( integerValue );
			value = valueString.c_str();
		}
		floatValue = (float)integerValue;
	} else if ( flags & CVAR_FLOAT ) {
		floatValue = (float)atof( value );
		if ( valueMin < valueMax ) {
			if ( floatValue < valueMin ) {
				floatValue = valueMin;
				clamped = true;
			} else if ( floatValue > valueMax ) {
				floatValue = valueMax;
				clamped = true;
			}
		}
		if ( clamped || !idStr::IsNumeric( value ) ) {
			valueString = idStr( floatValue );
			value = valueString.c_str();
		}
		integerValue = (int)floatValue;
	} else {
		if ( valueStrings && valueStrings[0] ) {
			integerValue = 0;
			for ( int i = 0; valueStrings[i]; i++ ) {
				if ( valueString.Icmp( valueStrings[i] ) == 0 ) {
					integerValue = i;
					break;
				}
			}
			valueString = valueStrings[integerValue];
			value = valueString.c_str();
			floatValue = (float)integerValue;
		} else if ( valueString.Length() < 32 ) {
			floatValue = (float)atof( value );
			integerValue = (int)floatValue;
		} else {
			floatValue = 0.0f;
			integerValue = 0;
		}
	}
}
コード例 #15
0
/*
========================
ConvertCG2GLSL
========================
*/
idStr ConvertCG2GLSL( const idStr & in, const char * name, bool isVertexProgram, idStr & uniforms ) {
	idStr program;
	program.ReAllocate( in.Length() * 2, false );

	idList< inOutVariable_t, TAG_RENDERPROG > varsIn;
	idList< inOutVariable_t, TAG_RENDERPROG > varsOut;
	idList< idStr > uniformList;

	idLexer src( LEXFL_NOFATALERRORS );
	src.LoadMemory( in.c_str(), in.Length(), name );

	bool inMain = false;
	const char * uniformArrayName = isVertexProgram ? VERTEX_UNIFORM_ARRAY_NAME : FRAGMENT_UNIFORM_ARRAY_NAME;
	char newline[128] = { "\n" };

	idToken token;
	while ( src.ReadToken( &token ) ) {

		// check for uniforms
		while ( token == "uniform" && src.CheckTokenString( "float4" ) ) {
			src.ReadToken( &token );
			uniformList.Append( token );

			// strip ': register()' from uniforms
			if ( src.CheckTokenString( ":" ) ) {
				if ( src.CheckTokenString( "register" ) ) {
					src.SkipUntilString( ";" );
				}
			}

			src.ReadToken( & token );
		}

		// convert the in/out structs
		if ( token == "struct" ) {
			if ( src.CheckTokenString( "VS_IN" ) ) {
				ParseInOutStruct( src, AT_VS_IN, varsIn );
				program += "\n\n";
				for ( int i = 0; i < varsIn.Num(); i++ ) {
					if ( varsIn[i].declareInOut ) {
						program += "in " + varsIn[i].type + " " + varsIn[i].nameGLSL + ";\n";
					}
				}
				continue;
			} else if ( src.CheckTokenString( "VS_OUT" ) ) {
				ParseInOutStruct( src, AT_VS_OUT, varsOut );
				program += "\n";
				for ( int i = 0; i < varsOut.Num(); i++ ) {
					if ( varsOut[i].declareInOut ) {
						program += "out " + varsOut[i].type + " " + varsOut[i].nameGLSL + ";\n";
					}
				}
				continue;
			} else if ( src.CheckTokenString( "PS_IN" ) ) {
				ParseInOutStruct( src, AT_PS_IN, varsIn );
				program += "\n\n";
				for ( int i = 0; i < varsIn.Num(); i++ ) {
					if ( varsIn[i].declareInOut ) {
						program += "in " + varsIn[i].type + " " + varsIn[i].nameGLSL + ";\n";
					}
				}
				inOutVariable_t var;
				var.type = "vec4";
				var.nameCg = "position";
				var.nameGLSL = "gl_FragCoord";
				varsIn.Append( var );
				continue;
			} else if ( src.CheckTokenString( "PS_OUT" ) ) {
				ParseInOutStruct( src, AT_PS_OUT, varsOut );
				program += "\n";
				for ( int i = 0; i < varsOut.Num(); i++ ) {
					if ( varsOut[i].declareInOut ) {
						program += "out " + varsOut[i].type + " " + varsOut[i].nameGLSL + ";\n";
					}
				}
				continue;
			}
		}

		// strip 'static'
		if ( token == "static" ) {
			program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
			src.SkipWhiteSpace( true ); // remove white space between 'static' and the next token
			continue;
		}

		// strip ': register()' from uniforms
		if ( token == ":" ) {
			if ( src.CheckTokenString( "register" ) ) {
				src.SkipUntilString( ";" );
				program += ";";
				continue;
			}
		}

		// strip in/program parameters from main
		if ( token == "void" && src.CheckTokenString( "main" ) ) {
			src.ExpectTokenString( "(" );
			while( src.ReadToken( &token ) ) {
				if ( token == ")" ) {
					break;
				}
			}

			program += "\nvoid main()";
			inMain = true;
			continue;
		}

		// strip 'const' from local variables in main()
		if ( token == "const" && inMain ) {
			program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
			src.SkipWhiteSpace( true ); // remove white space between 'const' and the next token
			continue;
		}

		// maintain indentation
		if ( token == "{" ) {
			program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
			program += "{";

			int len = Min( idStr::Length( newline ) + 1, (int)sizeof( newline ) - 1 );
			newline[len - 1] = '\t';
			newline[len - 0] = '\0';
			continue;
		}
		if ( token == "}" ) {
			int len = Max( idStr::Length( newline ) - 1, 0 );
			newline[len] = '\0';

			program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
			program += "}";
			continue;
		}

		// check for a type conversion
		bool foundType = false;
		for ( int i = 0; typeConversion[i].typeCG != NULL; i++ ) {
			if ( token.Cmp( typeConversion[i].typeCG ) == 0 ) {
				program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
				program += typeConversion[i].typeGLSL;
				foundType = true;
				break;
			}
		}
		if ( foundType ) {
			continue;
		}

		if ( r_useUniformArrays.GetBool() ) {
			// check for uniforms that need to be converted to the array
			bool isUniform = false;
			for ( int i = 0; i < uniformList.Num(); i++ ) {
				if ( token == uniformList[i] ) {
					program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
					program += va( "%s[%d /* %s */]", uniformArrayName, i, uniformList[i].c_str() );
					isUniform = true;
					break;
				}
			}
			if ( isUniform ) {
				continue;
			}
		}

		// check for input/output parameters
		if ( src.CheckTokenString( "." ) ) {

			if ( token == "vertex" || token == "fragment" ) {
				idToken member;
				src.ReadToken( &member );

				bool foundInOut = false;
				for ( int i = 0; i < varsIn.Num(); i++ ) {
					if ( member.Cmp( varsIn[i].nameCg ) == 0 ) {
						program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
						program += varsIn[i].nameGLSL;
						foundInOut = true;
						break;
					}
				}
				if ( !foundInOut ) {
					src.Error( "invalid input parameter %s.%s", token.c_str(), member.c_str() );
					program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
					program += token;
					program += ".";
					program += member;
				}
				continue;
			}

			if ( token == "result" ) {
				idToken member;
				src.ReadToken( &member );

				bool foundInOut = false;
				for ( int i = 0; i < varsOut.Num(); i++ ) {
					if ( member.Cmp( varsOut[i].nameCg ) == 0 ) {
						program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
						program += varsOut[i].nameGLSL;
						foundInOut = true;
						break;
					}
				}
				if ( !foundInOut ) {
					src.Error( "invalid output parameter %s.%s", token.c_str(), member.c_str() );
					program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
					program += token;
					program += ".";
					program += member;
				}
				continue;
			}

			program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
			program += token;
			program += ".";
			continue;
		}

		// check for a function conversion
		bool foundFunction = false;
		for ( int i = 0; builtinConversion[i].nameCG != NULL; i++ ) {
			if ( token.Cmp( builtinConversion[i].nameCG ) == 0 ) {
				program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
				program += builtinConversion[i].nameGLSL;
				foundFunction = true;
				break;
			}
		}
		if ( foundFunction ) {
			continue;
		}

		program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
		program += token;
	}

	idStr out;

	if ( isVertexProgram ) {
		out.ReAllocate( idStr::Length( vertexInsert ) + in.Length() * 2, false );
		out += vertexInsert;
	} else {
		out.ReAllocate( idStr::Length( fragmentInsert ) + in.Length() * 2, false );
		out += fragmentInsert;
	}

	if ( uniformList.Num() > 0 ) {
		if ( r_useUniformArrays.GetBool() ) {
			out += va( "\nuniform vec4 %s[%d];\n", uniformArrayName, uniformList.Num() );
		} else {
			out += "\n";
			for ( int i = 0; i < uniformList.Num(); i++ ) {
				out += "uniform vec4 ";
				out += uniformList[i];
				out += ";\n";
			}
		}
	}

	out += program;

	for ( int i = 0; i < uniformList.Num(); i++ ) {
		uniforms += uniformList[i];
		uniforms += "\n";
	}
	uniforms += "\n";

	return out;
}
コード例 #16
0
/*
========================
StripDeadCode
========================
*/
idStr StripDeadCode( const idStr & in, const char * name ) {
	if ( r_skipStripDeadCode.GetBool() ) {
		return in;
	}

	//idLexer src( LEXFL_NOFATALERRORS );
	idParser src( LEXFL_NOFATALERRORS );
	src.LoadMemory( in.c_str(), in.Length(), name );
	src.AddDefine("PC");

	idList< idCGBlock, TAG_RENDERPROG > blocks;

	blocks.SetNum( 100 );

	idToken token;
	while ( !src.EndOfFile() ) {
		idCGBlock & block = blocks.Alloc();
		// read prefix
		while ( src.ReadToken( &token ) ) {
			bool found = false;
			for ( int i = 0; i < numPrefixes; i++ ) {
				if ( token == prefixes[i] ) {
					found = true;
					break;
				}
			}
			if ( !found ) {
				for ( int i = 0; i < numTypes; i++ ) {
					if ( token == types[i] ) {
						found = true;
						break;
					}
					int typeLen = idStr::Length( types[i] );
					if ( token.Cmpn( types[i], typeLen ) == 0 ) {
						for ( int j = 0; j < numTypePosts; j++ ) {
							if ( idStr::Cmp( token.c_str() + typeLen, typePosts[j] ) == 0 ) {
								found = true;
								break;
							}
						}
						if ( found ) {
							break;
						}
					}
				}
			}
			if ( found ) {
				if ( block.prefix.Length() > 0 && token.WhiteSpaceBeforeToken() ) {
					block.prefix += ' ';
				}
				block.prefix += token;
			} else {
				src.UnreadToken( &token );
				break;
			}
		}
		if ( !src.ReadToken( &token ) ) {
			blocks.SetNum( blocks.Num() - 1 );
			break;
		}
		block.name = token;

		if ( src.PeekTokenString( "=" ) || src.PeekTokenString( ":" ) || src.PeekTokenString( "[" ) ) {
			src.ReadToken( &token );
			block.postfix = token;
			while ( src.ReadToken( &token ) ) {
				if ( token == ";" ) {
					block.postfix += ';';
					break;
				} else {
					if ( token.WhiteSpaceBeforeToken() ){
						block.postfix += ' ';
					}
					block.postfix += token;
				}
			}
		} else if ( src.PeekTokenString( "(" ) ) {
			idStr parms, body;
			src.ParseBracedSection( parms, -1, true, '(', ')' );
			if ( src.CheckTokenString( ";" ) ) {
				block.postfix = parms + ";";
			} else {
				src.ParseBracedSection( body, -1, true, '{', '}' );
				block.postfix = parms + " " + body;
			}
		} else if ( src.PeekTokenString( "{" ) ) {
			src.ParseBracedSection( block.postfix, -1, true, '{', '}' );
			if ( src.CheckTokenString( ";" ) ) {
				block.postfix += ';';
			}
		} else if ( src.CheckTokenString( ";" ) ) {
			block.postfix = idStr( ';' );
		} else {
			src.Warning( "Could not strip dead code -- unknown token %s\n", token.c_str() );
			return in;
		}
	}

	idList<int, TAG_RENDERPROG> stack;
	for ( int i = 0; i < blocks.Num(); i++ ) {
		blocks[i].used = ( ( blocks[i].name == "main" )
			|| blocks[i].name.Right( 4 ) == "_ubo"
			);

		if ( blocks[i].name == "include" ) {
			blocks[i].used = true;
			blocks[i].name = ""; // clear out the include tag
		}

		if ( blocks[i].used ) {
			stack.Append( i );
		}
	}

	while ( stack.Num() > 0 ) {
		int i = stack[stack.Num() - 1];
		stack.SetNum( stack.Num() - 1 );

		idLexer src( LEXFL_NOFATALERRORS );
		src.LoadMemory( blocks[i].postfix.c_str(), blocks[i].postfix.Length(), name );
		while ( src.ReadToken( &token ) ) {
			for ( int j = 0; j < blocks.Num(); j++ ) {
				if ( !blocks[j].used ) {
					if ( token == blocks[j].name ) {
						blocks[j].used = true;
						stack.Append( j );
					}
				}
			}
		}
	}

	idStr out;

	for ( int i = 0; i < blocks.Num(); i++ ) {
		if ( blocks[i].used ) {
			out += blocks[i].prefix;
			out += ' ';
			out += blocks[i].name;
			out += ' ';
			out += blocks[i].postfix;
			out += '\n';
		}
	}

	return out;
}