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