diff options
Diffstat (limited to 'devtools/goldsrc_port_scripts/port_models.py')
| -rw-r--r-- | devtools/goldsrc_port_scripts/port_models.py | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/devtools/goldsrc_port_scripts/port_models.py b/devtools/goldsrc_port_scripts/port_models.py new file mode 100644 index 0000000..bd5fcc1 --- /dev/null +++ b/devtools/goldsrc_port_scripts/port_models.py @@ -0,0 +1,226 @@ + +import msvcrt, os, sys, re, WildcardSearch, VisitFiles + + +def GetArg( argName, ifAtEnd='' ): + for i in range( 1, len( sys.argv ) ): + if argName.upper() == sys.argv[i].upper(): + if i+1 >= len( sys.argv ): + return ifAtEnd + else: + return sys.argv[i+1] + return None + + +def PrintUsage(): + print r'port_models.py -srcdir <directory with the QCs> -vproject <game directory>' + print r'Note: -srcdir represents the ROOT of the models directory, but it points at the model sources' + print r' instead of the model content.' + print r'ex: port_models.py -srcdir c:\hl2\models\tfc -vproject c:\hl2\tfc' + sys.exit( 1 ) + + +def FixFilename( filename ): + filename = filename.replace( '/', '\\' ) + if filename == '.\\': + return filename + else: + return re.compile( r'[^\.]?\.\\' ).sub( '', filename ) + + +def GetDirName( fullFilename ): + a = fullFilename.rfind( '/' ) + b = fullFilename.rfind( '\\' ) + if a == -1 and b == -1: + return FixFilename( fullFilename ) + else: + return FixFilename( fullFilename[0 : max(a,b)] ) + + +g_bAlwaysContinue = 0 +def CheckContinue(): + global g_bAlwaysContinue + if g_bAlwaysContinue: + return 1 + else: + sys.stdout.write( 'Continue [(Y)es/(N)o/(A)lways]? ' ) + r = str( msvcrt.getch() ).upper() + if r == 'Y': + return 1 + elif r == 'A': + g_bAlwaysContinue = 1 + return 1 + else: + return 0 + + +# +# Get command line args. +# +modelSourceDir = GetArg( '-srcdir' ) +vprojectDir = GetArg( '-vproject' ) +if not modelSourceDir or not vprojectDir: + PrintUsage() + +binDir = vprojectDir + '\\..\\bin' + +studiomdlFilename = binDir + '\\studiomdl.exe' +vtexFilename = binDir + '\\vtex.exe' +xwadFilename = binDir + '\\xwad.exe' +if not os.access( studiomdlFilename, os.F_OK ) or not os.access( vtexFilename, os.F_OK ) or not os.access( xwadFilename, os.F_OK ): + print 'Can\'t find vtex.exe, xwad.exe, or studiomdl.exe in bin directory %s.' % (binDir) + sys.exit( 1 ) + + + +# +# +# REGEX's and code to convert the QC file. +# +# +reModelName = re.compile( r'(?P<start>\$modelname\s+)(?P<stripout>.*models(\\|\/))(?P<keep>.+)', re.IGNORECASE ) +reCDTexture = re.compile( r'(?P<start>\$(cdTexture|cdmaterials)\s+)(?P<stripout>.*models(\\|\/))(?P<keep>.+)', re.IGNORECASE ) +reCD = re.compile( r'\$cd\s', re.IGNORECASE ) + +def ident( name=None ): + if name: + return r'(?P<' + name + r'>\s+((\".*?\")|([^\"]\S*)))' + else: + return r'\s+((\".*?\")|([^\"]\S*))' + +reAttachmentLine = re.compile( r'(?P<keep>.*\$attachment'+ident()+ident()+ident()+ident()+ident() + ')' + ident()+ident(), re.IGNORECASE ) + +g_DirToMaterialsMap = {} + +def EditQCFile( fullFilename ): + f = open( fullFilename, 'rt' ) + lines = f.readlines() + f.close() + + bDidMaterials = 0 + + outLines = [] + for line in lines: + if not reCD.search( line ): + # Strip out stuff before /models in the $modelname line. + m = reModelName.search( line ) + if m: + line = m.group('start') + m.group('keep' ) + '\n' + else: + m = reCDTexture.search( line ) + if m: + materialsDirName = 'models/' + m.group('keep') + bmpDir = m.group('keep') + g_DirToMaterialsMap[FixFilename(bmpDir.upper())] = materialsDirName + bDidMaterials = 1 + line = '$cdmaterials %s\n' % materialsDirName + + # Strip out the last 2 args on the $attachment line if they're using too many. + # Goldsrc studiomdl allowed 2 extra args but it ignored them. + m = reAttachmentLine.search( line ) + if m: + line = m.group('keep') + + outLines.append( line ) + + if not bDidMaterials: + print 'No $cdtexture line in %s so we don\'t know where to convert the BMPs into.' % (fullFilename) + sys.exit( 1 ) + + # + # Write the QC back out. + # + try: + f = open( fullFilename, 'wt' ) + except IOError: + print 'Can\'t open %s for writing.\nMake sure it is not read-only.' % fullFilename + sys.exit( 1 ) + f.writelines( outLines ) + f.close() + + + +# +# Convert all the QC files and backup the old ones. +# +print '--- Converting QC files and running studiomdl ---' + +def QCFileCallback( filename, relativeName, fullFilename ): + print '\t' + relativeName + + # First, backup the QC. + os.system( 'copy \"%s\" \"%s\" > out' % (fullFilename, fullFilename + ".OLD") ) + + # + # Now, make some edits. + # + EditQCFile( fullFilename ); + + # + # Run studiomdl on it. + # + cmd = '%s -vproject \"%s\" \"%s\" > out' % (studiomdlFilename, vprojectDir, fullFilename) + if os.system( cmd ) != 0: + lines = open( 'out', 'rt' ).readlines() + sys.stdout.writelines( lines ) + sys.exit( 1 ) + +VisitFiles.VisitFiles( modelSourceDir, WildcardSearch.GetRegExForDOSWildcard( '*.qc' ), QCFileCallback, None ) + + +# +# Now convert all the BMP files. +# +print '\n--- Converting BMP files and running vtex ---' +def BMPFileCallback( filename, relativeName, fullFilename ): + print '\t' + relativeName + + # Find out where we want to store this BMP's files under materials. + dirName = GetDirName( relativeName ) + + try: + cdMaterials = g_DirToMaterialsMap[dirName.upper()] + except: + #print '\tWarning: couldn\'t convert %s (don\'t know where to put it).' % (relativeName) + pass + else: + # + # Run XWAD. + # + cmd = '%s -quiet -bmpfile \"%s\" -basedir \"%s\"' % (xwadFilename, fullFilename, vprojectDir) + if os.system( cmd ) != 0: + print '\tError running xwad on %s' % fullFilename + if not CheckContinue(): + print '\tcmd: %s' % cmd + sys.exit( 1 ) + + # + # Move the TGA it generated into the right directory. + # + materialsrcDir = '%s\\materialsrc\\%s' % (vprojectDir, cdMaterials) + if not os.access( materialsrcDir, os.F_OK ) and os.system( 'md \"%s\"' % materialsrcDir ) != 0: + print 'Can\'t create or access directory %s.' % materialsrcDir + + materialsDir = '%s\\materials\\%s' % (vprojectDir, cdMaterials) + if not os.access( materialsDir, os.F_OK ) and os.system( 'md \"%s\"' % materialsDir ) != 0: + print 'Can\'t create or access directory %s.' % materialsDir + + baseTGAFilename = filename[0:-4] + '.tga' + generatedFilename = vprojectDir + '\\materialsrc\\' + baseTGAFilename + cmd = 'move \"%s\" \"%s\"' % (generatedFilename, materialsrcDir) + if os.system( cmd ) != 0: + print 'system( %s ) failed.' % cmd + + # + # Lastly, run vtex on it. + # + cmd = '%s -shader VertexLitGeneric -quiet \"%s\\%s\"' % (vtexFilename, materialsrcDir, baseTGAFilename) + if os.system( cmd ) != 0: + sys.exit( 1 ) + + +VisitFiles.VisitFiles( modelSourceDir, WildcardSearch.GetRegExForDOSWildcard( '*.bmp' ), BMPFileCallback, None ) + + + + |