summaryrefslogtreecommitdiff
path: root/devtools/goldsrc_port_scripts/port_models.py
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/goldsrc_port_scripts/port_models.py')
-rw-r--r--devtools/goldsrc_port_scripts/port_models.py226
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 )
+
+
+
+