refactor scripts parsing
This commit is contained in:
parent
71c72527af
commit
d897de13d5
|
|
@ -32,10 +32,20 @@ extern int scriptline;
|
|||
void LoadScriptFile( const char *filename, int index, bool verbose = true );
|
||||
void ParseFromMemory( char *buffer, int size );
|
||||
|
||||
/// \param[in] crossline true: write next token to \c token or return false on EOF
|
||||
/// \param[in] crossline false: find next token on the current line or emit \c Error
|
||||
bool GetToken( bool crossline );
|
||||
|
||||
/// \brief Signals that the current token was not used, and should be reported for the next \c GetToken().
|
||||
/// Only may be used once between the \c GetToken() calls.
|
||||
void UnGetToken( void );
|
||||
|
||||
/// \brief
|
||||
/// \return true, if there is another token on the line.
|
||||
bool TokenAvailable( void );
|
||||
|
||||
/// \brief Parses next token and emits \c Error, if it's not equal to \p match.
|
||||
/// Allowed to cross a line.
|
||||
void MatchToken( const char *match );
|
||||
|
||||
template<typename T>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "q3map2.h"
|
||||
#include "autopk3.h"
|
||||
#include "shaders.h"
|
||||
#include <map>
|
||||
|
||||
|
||||
|
|
@ -208,17 +209,11 @@ struct Exclusions
|
|||
};
|
||||
|
||||
static inline void parseEXblock( StrList& list, const char *exName ){
|
||||
if ( !GetToken( true ) || !strEqual( token, "{" ) ) {
|
||||
if ( !( GetToken( true ) && strEqual( token, "{" ) ) ) {
|
||||
Error( "ReadExclusionsFile: %s, line %d: { not found", exName, scriptline );
|
||||
}
|
||||
while ( 1 )
|
||||
while ( GetToken( true ) && !strEqual( token, "}" ) )
|
||||
{
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
if ( strEqual( token, "}" ) ) {
|
||||
break;
|
||||
}
|
||||
if ( strEqual( token, "{" ) ) {
|
||||
Error( "ReadExclusionsFile: %s, line %d: brace, opening twice in a row.", exName, scriptline );
|
||||
}
|
||||
|
|
@ -243,13 +238,8 @@ static const Exclusions parseEXfile( const char* filename ){
|
|||
ParseFromMemory( (char *) buffer, size );
|
||||
|
||||
/* tokenize it */
|
||||
while ( 1 )
|
||||
while ( GetToken( true ) ) /* test for end of file */
|
||||
{
|
||||
/* test for end of file */
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* blocks */
|
||||
if ( striEqual( token, "textures" ) ){
|
||||
parseEXblock( ex.textures, filename );
|
||||
|
|
@ -386,50 +376,31 @@ int pk3BSPMain( Args& args ){
|
|||
|
||||
/* load the shader */
|
||||
const auto scriptFile = stream( g_game->shaderPath, '/', file );
|
||||
LoadScriptFile( scriptFile, 0, dbg );
|
||||
|
||||
/* tokenize it */
|
||||
/* check if shader file has to be excluded */
|
||||
while ( !excludedByShader && !excludedByShaderFile )
|
||||
{
|
||||
/* test for end of file */
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* does it contain restricted shaders/textures? */
|
||||
if( ( excludedByShader = StrList_find( ex.shaders, token ) )
|
||||
|| ( excludedByShader = StrList_find( ex.pureTextures, token ) ) ){
|
||||
break;
|
||||
}
|
||||
|
||||
/* handle { } section */
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
if ( !strEqual( token, "{" ) ) {
|
||||
Error( "ParseShaderFile: %s, line %d: { not found!\nFound instead: %s\nFile location be: %s",
|
||||
scriptFile.c_str(), scriptline, token, g_strLoadedFileLocation );
|
||||
}
|
||||
|
||||
while ( 1 )
|
||||
if( !excludedByShaderFile ){
|
||||
/* tokenize it */
|
||||
LoadScriptFile( scriptFile, 0, false );
|
||||
while ( GetToken( true ) )
|
||||
{
|
||||
/* get the next token */
|
||||
if ( !GetToken( true ) ) {
|
||||
/* does it contain restricted shaders/textures? */
|
||||
if( ( excludedByShader = StrList_find( ex.shaders, token ) )
|
||||
|| ( excludedByShader = StrList_find( ex.pureTextures, token ) ) ){
|
||||
break;
|
||||
}
|
||||
if ( strEqual( token, "}" ) ) {
|
||||
break;
|
||||
|
||||
/* handle { } section */
|
||||
if ( !( GetToken( true ) && strEqual( token, "{" ) ) ) {
|
||||
Error( "ParseShaderFile: %s, line %d: { not found!\nFound instead: %s\nFile location be: %s",
|
||||
scriptFile.c_str(), scriptline, token, g_strLoadedFileLocation );
|
||||
}
|
||||
/* parse stage directives */
|
||||
if ( strEqual( token, "{" ) ) {
|
||||
while ( 1 )
|
||||
{
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
if ( strEqual( token, "}" ) ) {
|
||||
break;
|
||||
|
||||
while ( GetToken( true ) && !strEqual( token, "}" ) )
|
||||
{
|
||||
/* parse stage directives */
|
||||
if ( strEqual( token, "{" ) ) {
|
||||
while ( GetToken( true ) && !strEqual( token, "}" ) )
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -437,13 +408,9 @@ int pk3BSPMain( Args& args ){
|
|||
}
|
||||
|
||||
/* tokenize it again */
|
||||
LoadScriptFile( scriptFile, 0, false );
|
||||
while ( 1 )
|
||||
LoadScriptFile( scriptFile, 0, dbg );
|
||||
while ( GetToken( true ) )
|
||||
{
|
||||
/* test for end of file */
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
//dump shader names
|
||||
if( dbg )
|
||||
Sys_Printf( "%s\n", token );
|
||||
|
|
@ -452,25 +419,14 @@ int pk3BSPMain( Args& args ){
|
|||
String64 *wantShader = StrList_find( pk3Shaders, token );
|
||||
|
||||
/* handle { } section */
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
if ( !strEqual( token, "{" ) ) {
|
||||
if ( !( GetToken( true ) && strEqual( token, "{" ) ) ) {
|
||||
Error( "ParseShaderFile: %s, line %d: { not found!\nFound instead: %s\nFile location be: %s",
|
||||
scriptFile.c_str(), scriptline, token, g_strLoadedFileLocation );
|
||||
}
|
||||
|
||||
bool hasmap = false;
|
||||
while ( 1 )
|
||||
while ( GetToken( true ) && !strEqual( token, "}" ) )
|
||||
{
|
||||
/* get the next token */
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
if ( strEqual( token, "}" ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
shader stages (passes)
|
||||
|
|
@ -478,14 +434,8 @@ int pk3BSPMain( Args& args ){
|
|||
|
||||
/* parse stage directives */
|
||||
if ( strEqual( token, "{" ) ) {
|
||||
while ( 1 )
|
||||
while ( GetToken( true ) && !strEqual( token, "}" ) )
|
||||
{
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
if ( strEqual( token, "}" ) ) {
|
||||
break;
|
||||
}
|
||||
if ( strEqual( token, "{" ) ) {
|
||||
Sys_FPrintf( SYS_WRN, "WARNING9: %s : line %d : opening brace inside shader stage\n", scriptFile.c_str(), scriptline );
|
||||
}
|
||||
|
|
@ -543,7 +493,7 @@ int pk3BSPMain( Args& args ){
|
|||
|
||||
/* ignore bogus paths */
|
||||
if ( !strEqual( token, "-" ) && !striEqual( token, "full" ) ) {
|
||||
char* const skysidestring = token + strcatQ( token, "_@@.tga", sizeof( token ) ) - 6;
|
||||
char* const skysidestring = token + strcatQ( token, "_@@.tga", std::size( token ) ) - 6;
|
||||
for( const auto side : { "up", "dn", "lf", "rt", "bk", "ft" } ){
|
||||
memcpy( skysidestring, side, 2 );
|
||||
tex2list( pk3Textures, ex.textures, NULL );
|
||||
|
|
@ -842,7 +792,7 @@ int repackBSPMain( Args& args ){
|
|||
|
||||
//Parse Shader Files
|
||||
Sys_Printf( "\t\nParsing shaders....\n\n" );
|
||||
StringOutputStream shaderText( 4096 );
|
||||
ShaderTextCollector text;
|
||||
StringOutputStream allShaders( 1048576 );
|
||||
|
||||
for ( const CopiedString& file : pk3Shaderfiles ){
|
||||
|
|
@ -851,20 +801,12 @@ int repackBSPMain( Args& args ){
|
|||
LoadScriptFile( scriptFile, 0, dbg );
|
||||
|
||||
/* tokenize it */
|
||||
while ( 1 )
|
||||
while ( text.GetToken( true ) ) /* test for end of file */
|
||||
{
|
||||
int line = scriptline;
|
||||
/* test for end of file */
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
//dump shader names
|
||||
if( dbg )
|
||||
Sys_Printf( "%s\n", token );
|
||||
|
||||
shaderText.clear();
|
||||
shaderText << token;
|
||||
|
||||
if ( strchr( token, '\\') != NULL ){
|
||||
Sys_FPrintf( SYS_WRN, "WARNING1: %s : %s : shader name with backslash\n", file.c_str(), token );
|
||||
}
|
||||
|
|
@ -873,49 +815,19 @@ int repackBSPMain( Args& args ){
|
|||
String64 *wantShader = StrList_find( pk3Shaders, token );
|
||||
|
||||
/* handle { } section */
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
if ( !strEqual( token, "{" ) ) {
|
||||
if ( !( text.GetToken( true ) && strEqual( token, "{" ) ) ) {
|
||||
Error( "ParseShaderFile: %s, line %d: { not found!\nFound instead: %s\nFile location be: %s",
|
||||
scriptFile.c_str(), scriptline, token, g_strLoadedFileLocation );
|
||||
}
|
||||
shaderText << "\n{";
|
||||
|
||||
bool hasmap = false;
|
||||
|
||||
while ( 1 )
|
||||
while ( text.GetToken( true ) && !strEqual( token, "}" ) )
|
||||
{
|
||||
line = scriptline;
|
||||
/* get the next token */
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
if ( strEqual( token, "}" ) ) {
|
||||
shaderText << "\n}\n\n";
|
||||
break;
|
||||
}
|
||||
/* parse stage directives */
|
||||
if ( strEqual( token, "{" ) ) {
|
||||
bool tokenready = false;
|
||||
shaderText << "\n\t{";
|
||||
while ( 1 )
|
||||
while ( text.GetToken( true ) && !strEqual( token, "}" ) )
|
||||
{
|
||||
/* detour of TokenAvailable() '~' */
|
||||
if ( tokenready )
|
||||
tokenready = false;
|
||||
else
|
||||
line = scriptline;
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
if ( strEqual( token, "}" ) ) {
|
||||
shaderText << "\n\t}";
|
||||
break;
|
||||
}
|
||||
if ( strEqual( token, "{" ) ) {
|
||||
shaderText << "\n\t{";
|
||||
Sys_FPrintf( SYS_WRN, "WARNING9: %s : line %d : opening brace inside shader stage\n", scriptFile.c_str(), scriptline );
|
||||
}
|
||||
/* skip the shader */
|
||||
if ( !wantShader )
|
||||
continue;
|
||||
|
|
@ -923,7 +835,6 @@ int repackBSPMain( Args& args ){
|
|||
/* digest any images */
|
||||
if ( striEqual( token, "map" ) ||
|
||||
striEqual( token, "clampMap" ) ) {
|
||||
shaderText << "\n\t\t" << token;
|
||||
hasmap = true;
|
||||
|
||||
/* get an image */
|
||||
|
|
@ -931,27 +842,21 @@ int repackBSPMain( Args& args ){
|
|||
if ( token[ 0 ] != '*' && token[ 0 ] != '$' ) {
|
||||
tex2list( pk3Textures, ex.textures, &rex.textures );
|
||||
}
|
||||
shaderText << " " << token;
|
||||
text.tokenAppend(); // append token, modified by tex2list()
|
||||
}
|
||||
else if ( striEqual( token, "animMap" ) ||
|
||||
striEqual( token, "clampAnimMap" ) ) {
|
||||
shaderText << "\n\t\t" << token;
|
||||
hasmap = true;
|
||||
|
||||
GetToken( false );// skip num
|
||||
shaderText << " " << token;
|
||||
text.GetToken( false );// skip num
|
||||
while ( TokenAvailable() ){
|
||||
GetToken( false );
|
||||
tex2list( pk3Textures, ex.textures, &rex.textures );
|
||||
shaderText << " " << token;
|
||||
text.GetToken( false ); // append token, modified by tex2list()
|
||||
}
|
||||
tokenready = true;
|
||||
}
|
||||
else if ( striEqual( token, "videoMap" ) ){
|
||||
shaderText << "\n\t\t" << token;
|
||||
hasmap = true;
|
||||
GetToken( false );
|
||||
shaderText << " " << token;
|
||||
text.GetToken( false );
|
||||
FixDOSName( token );
|
||||
if ( strchr( token, '/' ) == NULL ){
|
||||
strcpy( token, stream( "video/", token ) );
|
||||
|
|
@ -964,18 +869,6 @@ int repackBSPMain( Args& args ){
|
|||
else if ( striEqual( token, "mapComp" ) || striEqual( token, "mapNoComp" ) || striEqual( token, "animmapcomp" ) || striEqual( token, "animmapnocomp" ) ){
|
||||
Sys_FPrintf( SYS_WRN, "WARNING7: %s : %s shader\n", wantShader->c_str(), token );
|
||||
hasmap = true;
|
||||
if ( line == scriptline ){
|
||||
shaderText << " " << token;
|
||||
}
|
||||
else{
|
||||
shaderText << "\n\t\t" << token;
|
||||
}
|
||||
}
|
||||
else if ( line == scriptline ){
|
||||
shaderText << " " << token;
|
||||
}
|
||||
else{
|
||||
shaderText << "\n\t\t" << token;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -985,50 +878,28 @@ int repackBSPMain( Args& args ){
|
|||
|
||||
/* skyparms <outer image> <cloud height> <inner image> */
|
||||
else if ( striEqual( token, "skyParms" ) ) {
|
||||
shaderText << "\n\tskyParms ";
|
||||
hasmap = true;
|
||||
/* get image base */
|
||||
GetToken( false );
|
||||
shaderText << token;
|
||||
text.GetToken( false );
|
||||
|
||||
/* ignore bogus paths */
|
||||
if ( !strEqual( token, "-" ) && !striEqual( token, "full" ) ) {
|
||||
char* const skysidestring = token + strcatQ( token, "_@@.tga", sizeof( token ) ) - 6;
|
||||
char* const skysidestring = token + strcatQ( token, "_@@.tga", std::size( token ) ) - 6;
|
||||
for( const auto side : { "up", "dn", "lf", "rt", "bk", "ft" } ){
|
||||
memcpy( skysidestring, side, 2 );
|
||||
tex2list( pk3Textures, ex.textures, &rex.textures );
|
||||
}
|
||||
}
|
||||
/* skip rest of line */
|
||||
GetToken( false );
|
||||
shaderText << " " << token;
|
||||
GetToken( false );
|
||||
shaderText << " " << token;
|
||||
text.GetToken( false );
|
||||
text.GetToken( false );
|
||||
}
|
||||
else if ( striEqualPrefix( token, "implicit" ) ){
|
||||
Sys_FPrintf( SYS_WRN, "WARNING5: %s : %s shader\n", wantShader->c_str(), token );
|
||||
hasmap = true;
|
||||
if ( line == scriptline ){
|
||||
shaderText << " " << token;
|
||||
}
|
||||
else{
|
||||
shaderText << "\n\t" << token;
|
||||
}
|
||||
}
|
||||
else if ( striEqual( token, "fogparms" ) ){
|
||||
hasmap = true;
|
||||
if ( line == scriptline ){
|
||||
shaderText << " " << token;
|
||||
}
|
||||
else{
|
||||
shaderText << "\n\t" << token;
|
||||
}
|
||||
}
|
||||
else if ( line == scriptline ){
|
||||
shaderText << " " << token;
|
||||
}
|
||||
else{
|
||||
shaderText << "\n\t" << token;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1045,10 +916,12 @@ int repackBSPMain( Args& args ){
|
|||
wantShader = nullptr;
|
||||
}
|
||||
if ( wantShader ){
|
||||
allShaders << shaderText;
|
||||
allShaders << text.text << '\n';
|
||||
wantShader->clear();
|
||||
}
|
||||
}
|
||||
/* reset collector */
|
||||
text.clear();
|
||||
}
|
||||
}
|
||||
/* TODO: RTCW's mapComp, mapNoComp, animmapcomp, animmapnocomp; nocompress?; ET's implicitmap, implicitblend, implicitmask */
|
||||
|
|
|
|||
|
|
@ -220,36 +220,21 @@ void Convert_ReferenceLightmaps( const char* base, std::vector<int>& lmIndices )
|
|||
sprintf( shaderfile, "%s/q3map2_%s.shader", g_game->shaderPath, base );
|
||||
LoadScriptFile( shaderfile, 0 );
|
||||
/* tokenize it */
|
||||
while ( 1 )
|
||||
while ( GetToken( true ) ) /* test for end of file */
|
||||
{
|
||||
/* test for end of file */
|
||||
if ( !GetToken( true ) )
|
||||
break;
|
||||
|
||||
char shadername[256];
|
||||
strcpy( shadername, token );
|
||||
|
||||
/* handle { } section */
|
||||
if ( !GetToken( true ) )
|
||||
break;
|
||||
if ( !strEqual( token, "{" ) )
|
||||
if ( !( GetToken( true ) && strEqual( token, "{" ) ) )
|
||||
Error( "ParseShaderFile: %s, line %d: { not found!\nFound instead: %s\nFile location be: %s",
|
||||
shaderfile, scriptline, token, g_strLoadedFileLocation );
|
||||
while ( 1 )
|
||||
while ( GetToken( true ) && !strEqual( token, "}" ) )
|
||||
{
|
||||
/* get the next token */
|
||||
if ( !GetToken( true ) )
|
||||
break;
|
||||
if ( strEqual( token, "}" ) )
|
||||
break;
|
||||
/* parse stage directives */
|
||||
if ( strEqual( token, "{" ) ) {
|
||||
while ( 1 )
|
||||
while ( GetToken( true ) && !strEqual( token, "}" ) )
|
||||
{
|
||||
if ( !GetToken( true ) )
|
||||
break;
|
||||
if ( strEqual( token, "}" ) )
|
||||
break;
|
||||
if ( strEqual( token, "{" ) )
|
||||
Sys_FPrintf( SYS_WRN, "WARNING9: %s : line %d : opening brace inside shader stage\n", shaderfile, scriptline );
|
||||
|
||||
|
|
|
|||
|
|
@ -967,25 +967,13 @@ static void ParseRawBrush( bool onlyLights ){
|
|||
}
|
||||
|
||||
/* parse sides */
|
||||
while ( 1 )
|
||||
while ( GetToken( true ) && !strEqual( token, "}" ) )
|
||||
{
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
if ( strEqual( token, "}" ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* ttimo : bp: here we may have to jump over brush epairs (only used in editor) */
|
||||
if ( g_brushType == EBrushType::Bp ) {
|
||||
while ( 1 )
|
||||
while ( !strEqual( token, "(" ) )
|
||||
{
|
||||
if ( !strEqual( token, "(" ) ) {
|
||||
GetToken( false );
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
GetToken( false );
|
||||
GetToken( true );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
/* dependencies */
|
||||
#include "q3map2.h"
|
||||
#include "shaders.h"
|
||||
|
||||
|
||||
|
||||
|
|
@ -845,111 +846,41 @@ shaderInfo_t *ShaderInfoForShader( const char *shaderName ){
|
|||
|
||||
|
||||
|
||||
/*
|
||||
GetTokenAppend() - ydnar
|
||||
gets a token and appends its text to the specified buffer
|
||||
*/
|
||||
static void Parse1DMatrixAppend( ShaderTextCollector& text, int x, float *m ){
|
||||
|
||||
static int oldScriptLine = 0;
|
||||
static int tabDepth = 0;
|
||||
|
||||
bool GetTokenAppend( char *buffer, bool crossline ){
|
||||
bool r;
|
||||
int i;
|
||||
|
||||
|
||||
/* get the token */
|
||||
r = GetToken( crossline );
|
||||
if ( !r || buffer == NULL || strEmpty( token ) ) {
|
||||
return r;
|
||||
}
|
||||
|
||||
/* pre-tabstops */
|
||||
if ( token[ 0 ] == '}' ) {
|
||||
tabDepth--;
|
||||
}
|
||||
|
||||
/* append? */
|
||||
if ( oldScriptLine != scriptline ) {
|
||||
strcat( buffer, "\n" );
|
||||
for ( i = 0; i < tabDepth; i++ )
|
||||
strcat( buffer, "\t" );
|
||||
}
|
||||
else{
|
||||
strcat( buffer, " " );
|
||||
}
|
||||
oldScriptLine = scriptline;
|
||||
strcat( buffer, token );
|
||||
|
||||
/* post-tabstops */
|
||||
if ( token[ 0 ] == '{' ) {
|
||||
tabDepth++;
|
||||
}
|
||||
|
||||
/* return */
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
void Parse1DMatrixAppend( char *buffer, int x, float *m ){
|
||||
|
||||
if ( !GetTokenAppend( buffer, true ) || !strEqual( token, "(" ) ) {
|
||||
if ( !text.GetToken( true ) || !strEqual( token, "(" ) ) {
|
||||
Error( "Parse1DMatrixAppend(): line %d: ( not found!\nFile location be: %s\n", scriptline, g_strLoadedFileLocation );
|
||||
}
|
||||
for ( int i = 0; i < x; i++ )
|
||||
{
|
||||
if ( !GetTokenAppend( buffer, false ) ) {
|
||||
if ( !text.GetToken( false ) ) {
|
||||
Error( "Parse1DMatrixAppend(): line %d: Number not found!\nFile location be: %s\n", scriptline, g_strLoadedFileLocation );
|
||||
}
|
||||
m[ i ] = atof( token );
|
||||
}
|
||||
if ( !GetTokenAppend( buffer, true ) || !strEqual( token, ")" ) ) {
|
||||
if ( !text.GetToken( true ) || !strEqual( token, ")" ) ) {
|
||||
Error( "Parse1DMatrixAppend(): line %d: ) not found!\nFile location be: %s\n", scriptline, g_strLoadedFileLocation );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
ParseShaderFile()
|
||||
parses a shader file into discrete shaderInfo_t
|
||||
*/
|
||||
|
||||
static void ParseShaderFile( const char *filename ){
|
||||
int i;
|
||||
shaderInfo_t *si;
|
||||
char shaderText[ 8192 ]; /* ydnar: fixme (make this bigger?) */
|
||||
|
||||
|
||||
/* init */
|
||||
si = NULL;
|
||||
strClear( shaderText );
|
||||
ShaderTextCollector text;
|
||||
|
||||
/* load the shader */
|
||||
LoadScriptFile( filename, 0 );
|
||||
|
||||
/* tokenize it */
|
||||
while ( 1 )
|
||||
while ( GetToken( true ) ) /* test for end of file */
|
||||
{
|
||||
/* copy shader text to the shaderinfo */
|
||||
if ( si != NULL && !strEmpty( shaderText ) ) {
|
||||
strcat( shaderText, "\n" );
|
||||
si->shaderText = copystring( shaderText );
|
||||
//% if( vector3_length( si->vecs[ 0 ] ) )
|
||||
//% Sys_Printf( "%s\n", shaderText );
|
||||
}
|
||||
|
||||
/* ydnar: clear shader text buffer */
|
||||
strClear( shaderText );
|
||||
|
||||
/* test for end of file */
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* shader name is initial token */
|
||||
si = AllocShaderInfo();
|
||||
shaderInfo_t *si = AllocShaderInfo();
|
||||
|
||||
/* ignore ":q3map" suffix */
|
||||
if( striEqualSuffix( token, ":q3map" ) )
|
||||
|
|
@ -958,31 +889,13 @@ static void ParseShaderFile( const char *filename ){
|
|||
si->shader << token;
|
||||
|
||||
/* handle { } section */
|
||||
if ( !GetTokenAppend( shaderText, true ) ) {
|
||||
break;
|
||||
}
|
||||
if ( !strEqual( token, "{" ) ) {
|
||||
if ( si != NULL ) {
|
||||
Error( "ParseShaderFile(): %s, line %d: { not found!\nFound instead: %s\nLast known shader: %s\nFile location be: %s\n",
|
||||
filename, scriptline, token, si->shader.c_str(), g_strLoadedFileLocation );
|
||||
}
|
||||
else{
|
||||
Error( "ParseShaderFile(): %s, line %d: { not found!\nFound instead: %s\nFile location be: %s\n",
|
||||
filename, scriptline, token, g_strLoadedFileLocation );
|
||||
}
|
||||
if ( !( text.GetToken( true ) && strEqual( token, "{" ) ) ) {
|
||||
Error( "ParseShaderFile(): %s, line %d: { not found!\nFound instead: %s\nLast known shader: %s\nFile location be: %s\n",
|
||||
filename, scriptline, token, si->shader.c_str(), g_strLoadedFileLocation );
|
||||
}
|
||||
|
||||
while ( 1 )
|
||||
while ( text.GetToken( true ) && !strEqual( token, "}" ) )
|
||||
{
|
||||
/* get the next token */
|
||||
if ( !GetTokenAppend( shaderText, true ) ) {
|
||||
break;
|
||||
}
|
||||
if ( strEqual( token, "}" ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
shader stages (passes)
|
||||
----------------------------------------------------------------- */
|
||||
|
|
@ -990,15 +903,8 @@ static void ParseShaderFile( const char *filename ){
|
|||
/* parse stage directives */
|
||||
if ( strEqual( token, "{" ) ) {
|
||||
si->hasPasses = true;
|
||||
while ( 1 )
|
||||
while ( text.GetToken( true ) && !strEqual( token, "}" ) )
|
||||
{
|
||||
if ( !GetTokenAppend( shaderText, true ) ) {
|
||||
break;
|
||||
}
|
||||
if ( strEqual( token, "}" ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* only care about images if we don't have a editor/light image */
|
||||
if ( si->editorImagePath.empty() && si->lightImagePath.empty() && si->implicitImagePath.empty() ) {
|
||||
/* digest any images */
|
||||
|
|
@ -1010,11 +916,11 @@ static void ParseShaderFile( const char *filename ){
|
|||
striEqual( token, "mapNoComp" ) ) {
|
||||
/* skip one token for animated stages */
|
||||
if ( striEqual( token, "animMap" ) || striEqual( token, "clampAnimMap" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
}
|
||||
|
||||
/* get an image */
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
if ( token[ 0 ] != '*' && token[ 0 ] != '$' ) {
|
||||
si->lightImagePath( PathExtensionless( token ) );
|
||||
|
||||
|
|
@ -1033,7 +939,7 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* match surfaceparm */
|
||||
else if ( striEqual( token, "surfaceparm" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
if ( !ApplySurfaceParm( token, &si->contentFlags, &si->surfaceFlags, &si->compileFlags ) ) {
|
||||
Sys_Warning( "Unknown surfaceparm: \"%s\"\n", token );
|
||||
}
|
||||
|
|
@ -1056,13 +962,13 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* tesssize is used to force liquid surfaces to subdivide */
|
||||
else if ( striEqual( token, "tessSize" ) || striEqual( token, "q3map_tessSize" ) /* sof2 */ ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->subdivisions = atof( token );
|
||||
}
|
||||
|
||||
/* cull none will set twoSided (ydnar: added disable too) */
|
||||
else if ( striEqual( token, "cull" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
if ( striEqual( token, "none" ) || striEqual( token, "disable" ) || striEqual( token, "twosided" ) ) {
|
||||
si->twoSided = true;
|
||||
}
|
||||
|
|
@ -1072,7 +978,7 @@ static void ParseShaderFile( const char *filename ){
|
|||
we catch this so autosprited surfaces become point
|
||||
lights instead of area lights */
|
||||
else if ( striEqual( token, "deformVertexes" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
|
||||
/* deformVertexes autosprite(2) */
|
||||
if ( striEqualPrefix( token, "autosprite" ) ) {
|
||||
|
|
@ -1092,16 +998,16 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
|
||||
/* get move amount */
|
||||
GetTokenAppend( shaderText, false ); amt[ 0 ] = atof( token );
|
||||
GetTokenAppend( shaderText, false ); amt[ 1 ] = atof( token );
|
||||
GetTokenAppend( shaderText, false ); amt[ 2 ] = atof( token );
|
||||
text.GetToken( false ); amt[ 0 ] = atof( token );
|
||||
text.GetToken( false ); amt[ 1 ] = atof( token );
|
||||
text.GetToken( false ); amt[ 2 ] = atof( token );
|
||||
|
||||
/* skip func */
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
|
||||
/* get base and amplitude */
|
||||
GetTokenAppend( shaderText, false ); base = atof( token );
|
||||
GetTokenAppend( shaderText, false ); amp = atof( token );
|
||||
text.GetToken( false ); base = atof( token );
|
||||
text.GetToken( false ); amp = atof( token );
|
||||
|
||||
/* calculate */
|
||||
si->minmax.mins = amt * base;
|
||||
|
|
@ -1111,23 +1017,23 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* light <value> (old-style flare specification) */
|
||||
else if ( striEqual( token, "light" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->flareShader = g_game->flareShader;
|
||||
}
|
||||
|
||||
/* ydnar: damageShader <shader> <health> (sof2 mods) */
|
||||
else if ( striEqual( token, "damageShader" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
if ( !strEmpty( token ) ) {
|
||||
si->damageShader = copystring( token );
|
||||
}
|
||||
GetTokenAppend( shaderText, false ); /* don't do anything with health */
|
||||
text.GetToken( false ); /* don't do anything with health */
|
||||
}
|
||||
|
||||
/* ydnar: enemy territory implicit shaders */
|
||||
else if ( striEqual( token, "implicitMap" ) ) {
|
||||
si->implicitMap = EImplicitMap::Opaque;
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
if ( strEqual( token, "-" ) ) {
|
||||
si->implicitImagePath = si->shader;
|
||||
}
|
||||
|
|
@ -1138,7 +1044,7 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
else if ( striEqual( token, "implicitMask" ) ) {
|
||||
si->implicitMap = EImplicitMap::Masked;
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
if ( strEqual( token, "-" ) ) {
|
||||
si->implicitImagePath = si->shader;
|
||||
}
|
||||
|
|
@ -1149,7 +1055,7 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
else if ( striEqual( token, "implicitBlend" ) ) {
|
||||
si->implicitMap = EImplicitMap::Blend;
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
if ( strEqual( token, "-" ) ) {
|
||||
si->implicitImagePath = si->shader;
|
||||
}
|
||||
|
|
@ -1165,26 +1071,26 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* qer_editorimage <image> */
|
||||
else if ( striEqual( token, "qer_editorImage" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->editorImagePath( PathExtensionless( token ) );
|
||||
}
|
||||
|
||||
/* ydnar: q3map_normalimage <image> (bumpmapping normal map) */
|
||||
else if ( striEqual( token, "q3map_normalImage" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->normalImagePath( PathExtensionless( token ) );
|
||||
}
|
||||
|
||||
/* q3map_lightimage <image> */
|
||||
else if ( striEqual( token, "q3map_lightImage" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->lightImagePath( PathExtensionless( token ) );
|
||||
}
|
||||
|
||||
/* ydnar: skyparms <outer image> <cloud height> <inner image> */
|
||||
else if ( striEqual( token, "skyParms" ) ) {
|
||||
/* get image base */
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
|
||||
/* ignore bogus paths */
|
||||
if ( !strEqual( token, "-" ) && !striEqual( token, "full" ) ) {
|
||||
|
|
@ -1197,8 +1103,8 @@ static void ParseShaderFile( const char *filename ){
|
|||
}
|
||||
|
||||
/* skip rest of line */
|
||||
GetTokenAppend( shaderText, false );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
text.GetToken( false );
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
|
|
@ -1222,11 +1128,11 @@ static void ParseShaderFile( const char *filename ){
|
|||
sun->style = si->lightStyle;
|
||||
|
||||
/* get color */
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
sun->color[ 0 ] = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
sun->color[ 1 ] = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
sun->color[ 2 ] = atof( token );
|
||||
|
||||
if ( colorsRGB ) {
|
||||
|
|
@ -1239,14 +1145,14 @@ static void ParseShaderFile( const char *filename ){
|
|||
ColorNormalize( sun->color );
|
||||
|
||||
/* scale color by brightness */
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
sun->photons = atof( token );
|
||||
|
||||
/* get sun angle/elevation */
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
const double a = degrees_to_radians( atof( token ) );
|
||||
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
const double b = degrees_to_radians( atof( token ) );
|
||||
|
||||
sun->direction = vector3_for_spherical( a, b );
|
||||
|
|
@ -1256,10 +1162,10 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* ydnar: get sun angular deviance/samples */
|
||||
if ( ext && TokenAvailable() ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
sun->deviance = degrees_to_radians( atof( token ) );
|
||||
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
sun->numSamples = atoi( token );
|
||||
}
|
||||
|
||||
|
|
@ -1283,7 +1189,7 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
|
||||
/* get shader */
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
//% Sys_FPrintf( SYS_VRB, "Shader %s has base shader %s\n", si->shader, token );
|
||||
oldWarnImage = warnImage;
|
||||
warnImage = false;
|
||||
|
|
@ -1312,25 +1218,25 @@ static void ParseShaderFile( const char *filename ){
|
|||
surfaceModel_t& model = si->surfaceModels.emplace_back();
|
||||
|
||||
/* get parameters */
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
model.model = token;
|
||||
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
model.density = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
model.odds = atof( token );
|
||||
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
model.minScale = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
model.maxScale = atof( token );
|
||||
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
model.minAngle = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
model.maxAngle = atof( token );
|
||||
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
model.oriented = ( token[ 0 ] == '1' );
|
||||
}
|
||||
|
||||
|
|
@ -1340,30 +1246,30 @@ static void ParseShaderFile( const char *filename ){
|
|||
foliage_t& foliage = si->foliage.emplace_back();
|
||||
|
||||
/* get parameters */
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
foliage.model = token;
|
||||
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
foliage.scale = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
foliage.density = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
foliage.odds = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
foliage.inverseAlpha = atoi( token );
|
||||
}
|
||||
|
||||
/* ydnar: q3map_bounce <value> (fraction of light to re-emit during radiosity passes) */
|
||||
else if ( striEqual( token, "q3map_bounce" ) || striEqual( token, "q3map_bounceScale" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->bounceScale = atof( token );
|
||||
}
|
||||
|
||||
/* ydnar/splashdamage: q3map_skyLight <value> <iterations> */
|
||||
else if ( striEqual( token, "q3map_skyLight" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->skyLightValue = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->skyLightIterations = atoi( token );
|
||||
|
||||
/* clamp */
|
||||
|
|
@ -1373,24 +1279,24 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* q3map_surfacelight <value> */
|
||||
else if ( striEqual( token, "q3map_surfacelight" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->value = atof( token );
|
||||
}
|
||||
|
||||
/* q3map_lightStyle (sof2/jk2 lightstyle) */
|
||||
else if ( striEqual( token, "q3map_lightStyle" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->lightStyle = std::clamp( atoi( token ), 0, LS_NONE );
|
||||
}
|
||||
|
||||
/* wolf: q3map_lightRGB <red> <green> <blue> */
|
||||
else if ( striEqual( token, "q3map_lightRGB" ) ) {
|
||||
si->color.set( 0 );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->color[ 0 ] = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->color[ 1 ] = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->color[ 2 ] = atof( token );
|
||||
if ( colorsRGB ) {
|
||||
si->color[0] = Image_LinearFloatFromsRGBFloat( si->color[0] );
|
||||
|
|
@ -1402,32 +1308,32 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* q3map_lightSubdivide <value> */
|
||||
else if ( striEqual( token, "q3map_lightSubdivide" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->lightSubdivide = atoi( token );
|
||||
}
|
||||
|
||||
/* q3map_backsplash <percent> <distance> */
|
||||
else if ( striEqual( token, "q3map_backsplash" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->backsplashFraction = atof( token ) * 0.01f;
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->backsplashDistance = atof( token );
|
||||
}
|
||||
|
||||
/* q3map_floodLight <r> <g> <b> <diste> <intensity> <light_direction_power> */
|
||||
else if ( striEqual( token, "q3map_floodLight" ) ) {
|
||||
/* get color */
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->floodlightRGB[ 0 ] = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->floodlightRGB[ 1 ] = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->floodlightRGB[ 2 ] = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->floodlightDistance = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->floodlightIntensity = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->floodlightDirectionScale = atof( token );
|
||||
if ( colorsRGB ) {
|
||||
si->floodlightRGB[0] = Image_LinearFloatFromsRGBFloat( si->floodlightRGB[0] );
|
||||
|
|
@ -1444,27 +1350,27 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* q3map_lightmapSampleSize <value> */
|
||||
else if ( striEqual( token, "q3map_lightmapSampleSize" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->lightmapSampleSize = atoi( token );
|
||||
}
|
||||
|
||||
/* q3map_lightmapSampleOffset <value> */
|
||||
else if ( striEqual( token, "q3map_lightmapSampleOffset" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->lightmapSampleOffset = atof( token );
|
||||
}
|
||||
|
||||
/* ydnar: q3map_lightmapFilterRadius <self> <other> */
|
||||
else if ( striEqual( token, "q3map_lightmapFilterRadius" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->lmFilterRadius = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->lightFilterRadius = atof( token );
|
||||
}
|
||||
|
||||
/* ydnar: q3map_lightmapAxis [xyz] */
|
||||
else if ( striEqual( token, "q3map_lightmapAxis" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
if ( striEqual( token, "x" ) ) {
|
||||
si->lightmapAxis = g_vector3_axis_x;
|
||||
}
|
||||
|
|
@ -1483,9 +1389,9 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* ydnar: q3map_lightmapSize <width> <height> (for autogenerated shaders + external tga lightmaps) */
|
||||
else if ( striEqual( token, "q3map_lightmapSize" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->lmCustomWidth = atoi( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->lmCustomHeight = atoi( token );
|
||||
|
||||
/* must be a power of 2 */
|
||||
|
|
@ -1500,7 +1406,7 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* ydnar: q3map_lightmapBrightness N (for autogenerated shaders + external tga lightmaps) */
|
||||
else if ( striEqual( token, "q3map_lightmapBrightness" ) || striEqual( token, "q3map_lightmapGamma" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->lmBrightness *= atof( token );
|
||||
if ( si->lmBrightness < 0 ) {
|
||||
si->lmBrightness = 1.0;
|
||||
|
|
@ -1509,7 +1415,7 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* q3map_vertexScale (scale vertex lighting by this fraction) */
|
||||
else if ( striEqual( token, "q3map_vertexScale" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->vertexScale *= atof( token );
|
||||
}
|
||||
|
||||
|
|
@ -1520,7 +1426,7 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* q3map_flare[Shader] <shader> */
|
||||
else if ( striEqual( token, "q3map_flare" ) || striEqual( token, "q3map_flareShader" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
if ( !strEmpty( token ) ) {
|
||||
si->flareShader = copystring( token );
|
||||
}
|
||||
|
|
@ -1528,7 +1434,7 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* q3map_backShader <shader> */
|
||||
else if ( striEqual( token, "q3map_backShader" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
if ( !strEmpty( token ) ) {
|
||||
si->backShader = copystring( token );
|
||||
}
|
||||
|
|
@ -1536,7 +1442,7 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* ydnar: q3map_cloneShader <shader> */
|
||||
else if ( striEqual( token, "q3map_cloneShader" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
if ( !strEmpty( token ) ) {
|
||||
si->cloneShader = copystring( token );
|
||||
}
|
||||
|
|
@ -1544,7 +1450,7 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* q3map_remapShader <shader> */
|
||||
else if ( striEqual( token, "q3map_remapShader" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
if ( !strEmpty( token ) ) {
|
||||
si->remapShader = copystring( token );
|
||||
}
|
||||
|
|
@ -1552,7 +1458,7 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* q3map_deprecateShader <shader> */
|
||||
else if ( striEqual( token, "q3map_deprecateShader" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
if ( !strEmpty( token ) ) {
|
||||
si->deprecateShader = copystring( token );
|
||||
}
|
||||
|
|
@ -1560,17 +1466,17 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* ydnar: q3map_offset <value> */
|
||||
else if ( striEqual( token, "q3map_offset" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->offset = atof( token );
|
||||
}
|
||||
|
||||
/* ydnar: q3map_fur <numlayers> <offset> <fade> */
|
||||
else if ( striEqual( token, "q3map_fur" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->furNumLayers = atoi( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->furOffset = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->furFade = atof( token );
|
||||
}
|
||||
|
||||
|
|
@ -1595,34 +1501,34 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* ydnar: gs mods: q3map_shadeAngle <degrees> */
|
||||
else if ( striEqual( token, "q3map_shadeAngle" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->shadeAngleDegrees = atof( token );
|
||||
}
|
||||
|
||||
/* ydnar: q3map_textureSize <width> <height> (substitute for q3map_lightimage derivation for terrain) */
|
||||
else if ( striEqual( token, "q3map_textureSize" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->shaderWidth = atoi( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
si->shaderHeight = atoi( token );
|
||||
}
|
||||
|
||||
/* ydnar: gs mods: q3map_tcGen <style> <parameters> */
|
||||
else if ( striEqual( token, "q3map_tcGen" ) ) {
|
||||
si->tcGen = true;
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
|
||||
/* q3map_tcGen vector <s vector> <t vector> */
|
||||
if ( striEqual( token, "vector" ) ) {
|
||||
Parse1DMatrixAppend( shaderText, 3, si->vecs[ 0 ].data() );
|
||||
Parse1DMatrixAppend( shaderText, 3, si->vecs[ 1 ].data() );
|
||||
Parse1DMatrixAppend( text, 3, si->vecs[ 0 ].data() );
|
||||
Parse1DMatrixAppend( text, 3, si->vecs[ 1 ].data() );
|
||||
}
|
||||
|
||||
/* q3map_tcGen ivector <1.0/s vector> <1.0/t vector> (inverse vector, easier for mappers to understand) */
|
||||
else if ( striEqual( token, "ivector" ) ) {
|
||||
Parse1DMatrixAppend( shaderText, 3, si->vecs[ 0 ].data() );
|
||||
Parse1DMatrixAppend( shaderText, 3, si->vecs[ 1 ].data() );
|
||||
for ( i = 0; i < 3; i++ )
|
||||
Parse1DMatrixAppend( text, 3, si->vecs[ 0 ].data() );
|
||||
Parse1DMatrixAppend( text, 3, si->vecs[ 1 ].data() );
|
||||
for ( size_t i = 0; i < 3; i++ )
|
||||
{
|
||||
si->vecs[ 0 ][ i ] = si->vecs[ 0 ][ i ] ? 1.0 / si->vecs[ 0 ][ i ] : 0;
|
||||
si->vecs[ 1 ][ i ] = si->vecs[ 1 ][ i ] ? 1.0 / si->vecs[ 1 ][ i ] : 0;
|
||||
|
|
@ -1665,19 +1571,19 @@ static void ParseShaderFile( const char *filename ){
|
|||
}
|
||||
|
||||
/* get type */
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
|
||||
/* alpha set|const A */
|
||||
if ( alpha && ( striEqual( token, "set" ) || striEqual( token, "const" ) ) ) {
|
||||
cm->type = EColorMod::AlphaSet;
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
cm->data[ 0 ] = atof( token );
|
||||
}
|
||||
|
||||
/* color|rgb set|const ( X Y Z ) */
|
||||
else if ( striEqual( token, "set" ) || striEqual( token, "const" ) ) {
|
||||
cm->type = EColorMod::ColorSet;
|
||||
Parse1DMatrixAppend( shaderText, 3, cm->data );
|
||||
Parse1DMatrixAppend( text, 3, cm->data );
|
||||
if ( colorsRGB ) {
|
||||
cm->data[0] = Image_LinearFloatFromsRGBFloat( cm->data[0] );
|
||||
cm->data[1] = Image_LinearFloatFromsRGBFloat( cm->data[1] );
|
||||
|
|
@ -1688,38 +1594,38 @@ static void ParseShaderFile( const char *filename ){
|
|||
/* alpha scale A */
|
||||
else if ( alpha && striEqual( token, "scale" ) ) {
|
||||
cm->type = EColorMod::AlphaScale;
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
cm->data[ 0 ] = atof( token );
|
||||
}
|
||||
|
||||
/* color|rgb scale ( X Y Z ) */
|
||||
else if ( striEqual( token, "scale" ) ) {
|
||||
cm->type = EColorMod::ColorScale;
|
||||
Parse1DMatrixAppend( shaderText, 3, cm->data );
|
||||
Parse1DMatrixAppend( text, 3, cm->data );
|
||||
}
|
||||
|
||||
/* dotProduct ( X Y Z ) */
|
||||
else if ( striEqual( token, "dotProduct" ) ) {
|
||||
cm->type = alpha? EColorMod::AlphaDotProduct : EColorMod::ColorDotProduct;
|
||||
Parse1DMatrixAppend( shaderText, 3, cm->data );
|
||||
Parse1DMatrixAppend( text, 3, cm->data );
|
||||
}
|
||||
|
||||
/* dotProductScale ( X Y Z MIN MAX ) */
|
||||
else if ( striEqual( token, "dotProductScale" ) ) {
|
||||
cm->type = alpha? EColorMod::AlphaDotProductScale : EColorMod::ColorDotProductScale;
|
||||
Parse1DMatrixAppend( shaderText, 5, cm->data );
|
||||
Parse1DMatrixAppend( text, 5, cm->data );
|
||||
}
|
||||
|
||||
/* dotProduct2 ( X Y Z ) */
|
||||
else if ( striEqual( token, "dotProduct2" ) ) {
|
||||
cm->type = alpha? EColorMod::AlphaDotProduct2 : EColorMod::ColorDotProduct2;
|
||||
Parse1DMatrixAppend( shaderText, 3, cm->data );
|
||||
Parse1DMatrixAppend( text, 3, cm->data );
|
||||
}
|
||||
|
||||
/* dotProduct2scale ( X Y Z MIN MAX ) */
|
||||
else if ( striEqual( token, "dotProduct2scale" ) ) {
|
||||
cm->type = alpha? EColorMod::AlphaDotProduct2Scale : EColorMod::ColorDotProduct2Scale;
|
||||
Parse1DMatrixAppend( shaderText, 5, cm->data );
|
||||
Parse1DMatrixAppend( text, 5, cm->data );
|
||||
}
|
||||
|
||||
/* volume */
|
||||
|
|
@ -1739,13 +1645,13 @@ static void ParseShaderFile( const char *filename ){
|
|||
float a, b;
|
||||
|
||||
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
|
||||
/* q3map_tcMod [translate | shift | offset] <s> <t> */
|
||||
if ( striEqual( token, "translate" ) || striEqual( token, "shift" ) || striEqual( token, "offset" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
a = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
b = atof( token );
|
||||
|
||||
TCModTranslate( si->mod, a, b );
|
||||
|
|
@ -1753,9 +1659,9 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* q3map_tcMod scale <s> <t> */
|
||||
else if ( striEqual( token, "scale" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
a = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
b = atof( token );
|
||||
|
||||
TCModScale( si->mod, a, b );
|
||||
|
|
@ -1763,7 +1669,7 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* q3map_tcMod rotate <s> <t> (fixme: make this communitive) */
|
||||
else if ( striEqual( token, "rotate" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
a = atof( token );
|
||||
TCModRotate( si->mod, a );
|
||||
}
|
||||
|
|
@ -1774,7 +1680,7 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* q3map_fogDir (direction a fog shader fades from transparent to opaque) */
|
||||
else if ( striEqual( token, "q3map_fogDir" ) ) {
|
||||
Parse1DMatrixAppend( shaderText, 3, si->fogDir.data() );
|
||||
Parse1DMatrixAppend( text, 3, si->fogDir.data() );
|
||||
VectorNormalize( si->fogDir );
|
||||
}
|
||||
|
||||
|
|
@ -1855,7 +1761,7 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* q3map_material (sof2) */
|
||||
else if ( striEqual( token, "q3map_material" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
text.GetToken( false );
|
||||
if ( !ApplySurfaceParm( StringOutputStream( 64 )( "*mat_", token ), &si->contentFlags, &si->surfaceFlags, &si->compileFlags ) ) {
|
||||
Sys_Warning( "Unknown material \"%s\"\n", token );
|
||||
}
|
||||
|
|
@ -1892,8 +1798,18 @@ static void ParseShaderFile( const char *filename ){
|
|||
----------------------------------------------------------------- */
|
||||
|
||||
/* ignore all other tokens on the line */
|
||||
while ( TokenAvailable() && GetTokenAppend( shaderText, false ) ) ;
|
||||
while ( TokenAvailable() )
|
||||
text.GetToken( false );
|
||||
}
|
||||
|
||||
/* copy shader text to the shaderinfo */
|
||||
text.text << '\n';
|
||||
si->shaderText = copystring( text.text );
|
||||
//% if( vector3_length( si->vecs[ 0 ] ) )
|
||||
//% Sys_Printf( "%s\n", si->shaderText );
|
||||
|
||||
/* ydnar: clear shader text buffer */
|
||||
text.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1905,9 +1821,6 @@ static void ParseShaderFile( const char *filename ){
|
|||
*/
|
||||
|
||||
static void ParseCustomInfoParms( void ){
|
||||
bool parsedContent, parsedSurface;
|
||||
|
||||
|
||||
/* file exists? */
|
||||
if ( vfsGetFileCount( "scripts/custinfoparms.txt" ) == 0 ) {
|
||||
return;
|
||||
|
|
@ -1919,21 +1832,12 @@ static void ParseCustomInfoParms( void ){
|
|||
/* clear the array */
|
||||
memset( custSurfaceParms, 0, sizeof( custSurfaceParms ) );
|
||||
numCustSurfaceParms = 0;
|
||||
parsedContent = parsedSurface = false;
|
||||
bool parsed = false;
|
||||
|
||||
/* parse custom contentflags */
|
||||
MatchToken( "{" );
|
||||
while ( 1 )
|
||||
while ( GetToken( true ) && !( parsed = strEqual( token, "}" ) ) )
|
||||
{
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( strEqual( token, "}" ) ) {
|
||||
parsedContent = true;
|
||||
break;
|
||||
}
|
||||
|
||||
custSurfaceParms[ numCustSurfaceParms ].name = copystring( token );
|
||||
GetToken( false );
|
||||
sscanf( token, "%x", &custSurfaceParms[ numCustSurfaceParms ].contentFlags );
|
||||
|
|
@ -1941,24 +1845,16 @@ static void ParseCustomInfoParms( void ){
|
|||
}
|
||||
|
||||
/* any content? */
|
||||
if ( !parsedContent ) {
|
||||
if ( !parsed ) {
|
||||
Sys_Warning( "Couldn't find valid custom contentsflag section\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* parse custom surfaceflags */
|
||||
MatchToken( "{" );
|
||||
while ( 1 )
|
||||
parsed = false;
|
||||
while ( GetToken( true ) && !( parsed = strEqual( token, "}" ) ) )
|
||||
{
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( strEqual( token, "}" ) ) {
|
||||
parsedSurface = true;
|
||||
break;
|
||||
}
|
||||
|
||||
custSurfaceParms[ numCustSurfaceParms ].name = copystring( token );
|
||||
GetToken( false );
|
||||
sscanf( token, "%x", &custSurfaceParms[ numCustSurfaceParms ].surfaceFlags );
|
||||
|
|
@ -1966,7 +1862,7 @@ static void ParseCustomInfoParms( void ){
|
|||
}
|
||||
|
||||
/* any content? */
|
||||
if ( !parsedContent ) {
|
||||
if ( !parsed ) {
|
||||
Sys_Warning( "Couldn't find valid custom surfaceflag section\n" );
|
||||
}
|
||||
}
|
||||
|
|
@ -2012,7 +1908,7 @@ void LoadShaderInfo( void ){
|
|||
};
|
||||
|
||||
if( !path_extension_is( token , "shader" ) )
|
||||
strcatQ( token, ".shader", sizeof( token ) );
|
||||
strcatQ( token, ".shader", std::size( token ) );
|
||||
/* new shader file */
|
||||
if ( !contains( token ) ) {
|
||||
shaderFiles.emplace_back( token );
|
||||
|
|
|
|||
87
tools/quake3/q3map2/shaders.h
Normal file
87
tools/quake3/q3map2/shaders.h
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/* -------------------------------------------------------------------------------
|
||||
|
||||
Copyright (C) 1999-2007 id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
This code has been altered significantly from its original form, to support
|
||||
several games based on the Quake III Arena engine, in the form of "Q3Map2."
|
||||
|
||||
------------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
class ShaderTextCollector
|
||||
{
|
||||
int oldScriptLine = -1;
|
||||
int tabDepth = 0;
|
||||
|
||||
void indent() {
|
||||
for ( int i = 0; i < tabDepth; ++i )
|
||||
text << '\t';
|
||||
}
|
||||
public:
|
||||
StringOutputStream text;
|
||||
void tokenAppend() {
|
||||
/* pre-tabstops */
|
||||
if ( strEqual( token, "}" ) ) {
|
||||
tabDepth--;
|
||||
if( tabDepth < 0 )
|
||||
Sys_Warning( "tabDepth < 0 in shader\n%s", text.c_str() );
|
||||
}
|
||||
|
||||
/* new line or append? */
|
||||
if( strEqual( token, "}" ) || strEqual( token, "{" ) ){ // special case: always on separate line
|
||||
text << '\n';
|
||||
indent();
|
||||
oldScriptLine = -1; // trigger new line for the next token
|
||||
}
|
||||
else if ( oldScriptLine != scriptline ) {
|
||||
oldScriptLine = scriptline;
|
||||
text << '\n';
|
||||
indent();
|
||||
}
|
||||
else{
|
||||
text << ' ';
|
||||
}
|
||||
text << token;
|
||||
|
||||
/* post-tabstops */
|
||||
if ( strEqual( token, "{" ) ) {
|
||||
tabDepth++;
|
||||
if( tabDepth > 2 )
|
||||
Sys_Warning( "tabDepth > 2 in shader\n%s", text.c_str() );
|
||||
}
|
||||
}
|
||||
bool GetToken( bool crossline ){
|
||||
const bool r = ::GetToken( crossline );
|
||||
if ( r && !strEmpty( token ) ) {
|
||||
tokenAppend();
|
||||
}
|
||||
return r;
|
||||
}
|
||||
void clear() {
|
||||
text.clear();
|
||||
oldScriptLine = -1; // 'scriptline' is not very reliable, thus some deduction; 1st line will be new line consistently
|
||||
tabDepth = 0;
|
||||
}
|
||||
};
|
||||
|
|
@ -305,13 +305,8 @@ void LoadSurfaceExtraFile( const char *path ){
|
|||
ParseFromMemory( (char *) buffer, size );
|
||||
|
||||
/* tokenize it */
|
||||
while ( 1 )
|
||||
while ( GetToken( true ) ) /* test for end of file */
|
||||
{
|
||||
/* test for end of file */
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* default? */
|
||||
if ( striEqual( token, "default" ) ) {
|
||||
se = &seDefault;
|
||||
|
|
@ -330,18 +325,11 @@ void LoadSurfaceExtraFile( const char *path ){
|
|||
}
|
||||
|
||||
/* handle { } section */
|
||||
if ( !GetToken( true ) || !strEqual( token, "{" ) ) {
|
||||
if ( !( GetToken( true ) && strEqual( token, "{" ) ) ) {
|
||||
Error( "ReadSurfaceExtraFile(): %s, line %d: { not found", srfPath, scriptline );
|
||||
}
|
||||
while ( 1 )
|
||||
while ( GetToken( true ) && !strEqual( token, "}" ) )
|
||||
{
|
||||
if ( !GetToken( true ) ) {
|
||||
break;
|
||||
}
|
||||
if ( strEqual( token, "}" ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* shader */
|
||||
if ( striEqual( token, "shader" ) ) {
|
||||
GetToken( false );
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user