X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=tools%2Fquake3%2Fq3data%2Fp3dlib.c;h=9de836146daac869e3927fc4e1eeb574b157ae1a;hb=03be668aca6168191b9adca7aec905c01c436146;hp=6afc3491e6185f3729e726c2b9bedf988d5c41ba;hpb=80378101101ca1762bbf5638a9e3566893096d8a;p=xonotic%2Fnetradiant.git diff --git a/tools/quake3/q3data/p3dlib.c b/tools/quake3/q3data/p3dlib.c index 6afc3491..9de83614 100644 --- a/tools/quake3/q3data/p3dlib.c +++ b/tools/quake3/q3data/p3dlib.c @@ -1,324 +1,337 @@ -#include "p3dlib.h" - -#ifdef _WIN32 -#include -#endif -#include -#include -#include - -#define MAX_POLYSETS 64 - -#if defined (__linux__) || defined (__APPLE__) -#define _strcmpi Q_stricmp -#define filelength Q_filelength -#define strlwr strlower -#endif -typedef struct -{ - long len; - - int numPairs; - char polysetNames[MAX_POLYSETS][256]; - char shaders[MAX_POLYSETS][256]; - - char *buffer, *curpos; -} p3d_t; - -static p3d_t p3d; - -static int P3DProcess(); -static int P3DGetToken( int restOfLine ); - -static char s_token[1024]; -static int s_curpair; - -/* -** P3DLoad -** -*/ -int P3DLoad( const char *filename ) -{ - FILE *fp = fopen( filename, "rb" ); - - if ( !fp ) - return 0; - - memset( &p3d, 0, sizeof( p3d ) ); - - p3d.len = filelength( fileno( fp ) ); - - p3d.curpos = p3d.buffer = malloc( p3d.len ); - - if ( fread( p3d.buffer, p3d.len, 1, fp ) != 1 ) - { - fclose( fp ); - return 0; - } - - fclose( fp ); - - return P3DProcess(); -} - -/* -** P3DClose -** -*/ -void P3DClose() -{ - if ( p3d.buffer ) - { - free( p3d.buffer ); - p3d.buffer = 0; - } -} - -int CharIsTokenDelimiter( int ch ) -{ - if ( ch <= 32 ) - return 1; - return 0; -} - -int P3DSkipToToken( const char *name ) -{ - while ( P3DGetToken( 0 ) ) - { - if ( !_strcmpi( s_token, name ) ) - return 1; - } - - return 0; -} - -/* -** P3DGetToken -** -*/ -int P3DGetToken( int restOfLine ) -{ - int i = 0; - - if ( p3d.buffer == 0 ) - return 0; - - if ( ( p3d.curpos - p3d.buffer ) == p3d.len ) - return 0; - - // skip over crap - while ( ( ( p3d.curpos - p3d.buffer ) < p3d.len ) && - ( *p3d.curpos <= 32 ) ) - { - p3d.curpos++; - } - - while ( ( p3d.curpos - p3d.buffer ) < p3d.len ) - { - s_token[i] = *p3d.curpos; - - p3d.curpos++; - i++; - - if ( ( CharIsTokenDelimiter( s_token[i-1] ) && !restOfLine ) || - ( ( s_token[i-1] == '\n' ) ) ) - { - s_token[i-1] = 0; - break; - } - } - - s_token[i] = 0; - - return 1; -} - -int P3DGetNextPair( char **psetName, char **associatedShader ) -{ - if ( s_curpair < p3d.numPairs ) - { - *psetName = p3d.polysetNames[s_curpair]; - *associatedShader = p3d.shaders[s_curpair]; - s_curpair++; - return 1; - } - - return 0; -} - -int P3DSkipToTokenInBlock( const char *name ) -{ - int iLevel = 0; - - while ( P3DGetToken( 0 ) ) - { - if ( !_strcmpi( s_token, "}" ) ) - iLevel--; - else if ( !_strcmpi( s_token, "{" ) ) - iLevel++; - - if ( !_strcmpi( s_token, name ) ) - return 1; - - if ( iLevel == 0 ) - { - return 0; - } - } - - return 0; -} - -/* -** P3DProcess -** -** Nothing fancy here. -*/ -int P3DProcess() -{ - - s_curpair = 0; - - // first token should be a string - P3DGetToken( 1 ); // Voodoo Ascii File - - // skip to the first Obj declaration - while ( P3DGetToken( 0 ) ) - { - if ( !_strcmpi( s_token, "Obj" ) ) - { - int j = 0, k = 0; - - if ( P3DSkipToToken( "Text" ) ) - { - if ( P3DSkipToTokenInBlock( "TMap" ) ) - { - char *p; - - if ( !P3DSkipToToken( "Path" ) ) - return 0; - - if ( !P3DGetToken( 1 ) ) - return 0; - - while ( s_token[j] != 0 ) - { - if ( s_token[j] == '\\' ) - { - j++; - p3d.shaders[p3d.numPairs][k] = '/'; - } - else - { - p3d.shaders[p3d.numPairs][k] = s_token[j]; - } - j++; - k++; - } - p3d.shaders[p3d.numPairs][k] = 0; - - // - // strip off any explicit extensions - // - if ( ( p = strrchr( p3d.shaders[p3d.numPairs], '/' ) ) != 0 ) - { - while ( *p ) - { - if ( *p == '.' ) - { - *p = 0; - break; - } - p++; - } - } - - // - // skip to the end of the Object and grab its name - // - if ( !P3DSkipToToken( "Name" ) ) - return 0; - - if ( P3DGetToken( 0 ) ) - { - // strip off leading 'Obj_' if it exists - if ( strstr( s_token, "Obj_" ) == s_token ) - strcpy( p3d.polysetNames[p3d.numPairs], s_token + strlen( "Obj_" ) ); - else - strcpy( p3d.polysetNames[p3d.numPairs], s_token ); - - // strip off trailing unused color information -// if ( strrchr( p3d.polysetNames[p3d.numPairs], '_' ) != 0 ) -// *strrchr( p3d.polysetNames[p3d.numPairs], '_' ) = 0; - - p3d.numPairs++; - } - else - { - return 0; - } - } - } - } - } - - s_curpair = 0; - - return 1; -} - -#if 0 -void SkinFromP3D( const char *file ) -{ - char filename[1024]; - char *psetName, *associatedShader; - - /* - ** a P3D file contains a list of polysets, each with a list of associated - ** texture names that constitute it's - ** - ** Thus: - ** - ** P3D file -> skin - ** polyset -> polyset - ** texture -> texture.SHADER becomes polyset's shader - */ - sprintf( filename, "%s/%s", g_cddir, file ); - - if ( !P3DLoad( filename ) ) - Error( "unable to load '%s'", filename ); - - while ( P3DGetNextPair( &psetName, &associatedShader ) ) - { - int i; - - // find the polyset in the object that this particular pset/shader pair - // corresponds to and append the shader to it - for ( i = 0; i < g_data.model.numSurfaces; i++ ) - { - if ( !_strcmpi( g_data.surfData[i].header.name, psetName) ) - { - char *p; - - if ( strstr( associatedShader, gamedir + 1 ) ) - { - p = strstr( associatedShader, gamedir + 1 ) + strlen( gamedir ) - 1; - } - else - { - p = associatedShader; - } - - strcpy( g_data.surfData[i].shaders[g_data.surfData[i].header.numShaders].name, p ); - - g_data.surfData[i].header.numShaders++; - } - } - - } - - P3DClose(); -} -#endif - - +/* + Copyright (C) 1999-2006 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 + */ + +#include "p3dlib.h" + +#ifdef WIN32 +#include +#endif +#include +#include +#include + +#define MAX_POLYSETS 64 + +#if defined ( __linux__ ) || defined ( __APPLE__ ) + #include "cmdlib.h" + #define _strcmpi Q_stricmp + #define strlwr strlower + #define filelength(f) Q_filelength(f) +#else + #define filelength(f) filelength(fileno(f)) +#endif +typedef struct +{ + long len; + + int numPairs; + char polysetNames[MAX_POLYSETS][256]; + char shaders[MAX_POLYSETS][256]; + + char *buffer, *curpos; +} p3d_t; + +static p3d_t p3d; + +static int P3DProcess(); +static int P3DGetToken( int restOfLine ); + +static char s_token[1024]; +static int s_curpair; + +/* +** P3DLoad +** +*/ +int P3DLoad( const char *filename ){ + FILE *fp = fopen( filename, "rb" ); + + if ( !fp ) { + return 0; + } + + memset( &p3d, 0, sizeof( p3d ) ); + + p3d.len = filelength( fp ); + + p3d.curpos = p3d.buffer = malloc( p3d.len ); + + if ( fread( p3d.buffer, p3d.len, 1, fp ) != 1 ) { + fclose( fp ); + return 0; + } + + fclose( fp ); + + return P3DProcess(); +} + +/* +** P3DClose +** +*/ +void P3DClose(){ + if ( p3d.buffer ) { + free( p3d.buffer ); + p3d.buffer = 0; + } +} + +int CharIsTokenDelimiter( int ch ){ + if ( ch <= 32 ) { + return 1; + } + return 0; +} + +int P3DSkipToToken( const char *name ){ + while ( P3DGetToken( 0 ) ) + { + if ( !_strcmpi( s_token, name ) ) { + return 1; + } + } + + return 0; +} + +/* +** P3DGetToken +** +*/ +int P3DGetToken( int restOfLine ){ + int i = 0; + + if ( p3d.buffer == 0 ) { + return 0; + } + + if ( ( p3d.curpos - p3d.buffer ) == p3d.len ) { + return 0; + } + + // skip over crap + while ( ( ( p3d.curpos - p3d.buffer ) < p3d.len ) && + ( *p3d.curpos <= 32 ) ) + { + p3d.curpos++; + } + + while ( ( p3d.curpos - p3d.buffer ) < p3d.len ) + { + s_token[i] = *p3d.curpos; + + p3d.curpos++; + i++; + + if ( ( CharIsTokenDelimiter( s_token[i - 1] ) && !restOfLine ) || + ( ( s_token[i - 1] == '\n' ) ) ) { + s_token[i - 1] = 0; + break; + } + } + + s_token[i] = 0; + + return 1; +} + +int P3DGetNextPair( char **psetName, char **associatedShader ){ + if ( s_curpair < p3d.numPairs ) { + *psetName = p3d.polysetNames[s_curpair]; + *associatedShader = p3d.shaders[s_curpair]; + s_curpair++; + return 1; + } + + return 0; +} + +int P3DSkipToTokenInBlock( const char *name ){ + int iLevel = 0; + + while ( P3DGetToken( 0 ) ) + { + if ( !_strcmpi( s_token, "}" ) ) { + iLevel--; + } + else if ( !_strcmpi( s_token, "{" ) ) { + iLevel++; + } + + if ( !_strcmpi( s_token, name ) ) { + return 1; + } + + if ( iLevel == 0 ) { + return 0; + } + } + + return 0; +} + +/* +** P3DProcess +** +** Nothing fancy here. +*/ +int P3DProcess(){ + + s_curpair = 0; + + // first token should be a string + P3DGetToken( 1 ); // Voodoo Ascii File + + // skip to the first Obj declaration + while ( P3DGetToken( 0 ) ) + { + if ( !_strcmpi( s_token, "Obj" ) ) { + int j = 0, k = 0; + + if ( P3DSkipToToken( "Text" ) ) { + if ( P3DSkipToTokenInBlock( "TMap" ) ) { + char *p; + + if ( !P3DSkipToToken( "Path" ) ) { + return 0; + } + + if ( !P3DGetToken( 1 ) ) { + return 0; + } + + while ( s_token[j] != 0 ) + { + if ( s_token[j] == '\\' ) { + j++; + p3d.shaders[p3d.numPairs][k] = '/'; + } + else + { + p3d.shaders[p3d.numPairs][k] = s_token[j]; + } + j++; + k++; + } + p3d.shaders[p3d.numPairs][k] = 0; + + // + // strip off any explicit extensions + // + if ( ( p = strrchr( p3d.shaders[p3d.numPairs], '/' ) ) != 0 ) { + while ( *p ) + { + if ( *p == '.' ) { + *p = 0; + break; + } + p++; + } + } + + // + // skip to the end of the Object and grab its name + // + if ( !P3DSkipToToken( "Name" ) ) { + return 0; + } + + if ( P3DGetToken( 0 ) ) { + // strip off leading 'Obj_' if it exists + if ( strstr( s_token, "Obj_" ) == s_token ) { + strcpy( p3d.polysetNames[p3d.numPairs], s_token + strlen( "Obj_" ) ); + } + else{ + strcpy( p3d.polysetNames[p3d.numPairs], s_token ); + } + + // strip off trailing unused color information +// if ( strrchr( p3d.polysetNames[p3d.numPairs], '_' ) != 0 ) +// *strrchr( p3d.polysetNames[p3d.numPairs], '_' ) = 0; + + p3d.numPairs++; + } + else + { + return 0; + } + } + } + } + } + + s_curpair = 0; + + return 1; +} + +#if 0 +void SkinFromP3D( const char *file ){ + char filename[1024]; + char *psetName, *associatedShader; + + /* + ** a P3D file contains a list of polysets, each with a list of associated + ** texture names that constitute it's + ** + ** Thus: + ** + ** P3D file -> skin + ** polyset -> polyset + ** texture -> texture.SHADER becomes polyset's shader + */ + sprintf( filename, "%s/%s", g_cddir, file ); + + if ( !P3DLoad( filename ) ) { + Error( "unable to load '%s'", filename ); + } + + while ( P3DGetNextPair( &psetName, &associatedShader ) ) + { + int i; + + // find the polyset in the object that this particular pset/shader pair + // corresponds to and append the shader to it + for ( i = 0; i < g_data.model.numSurfaces; i++ ) + { + if ( !_strcmpi( g_data.surfData[i].header.name, psetName ) ) { + char *p; + + if ( strstr( associatedShader, gamedir + 1 ) ) { + p = strstr( associatedShader, gamedir + 1 ) + strlen( gamedir ) - 1; + } + else + { + p = associatedShader; + } + + strcpy( g_data.surfData[i].shaders[g_data.surfData[i].header.numShaders].name, p ); + + g_data.surfData[i].header.numShaders++; + } + } + + } + + P3DClose(); +} +#endif