diff options
Diffstat (limited to 'devtools/bin/srgb_colorspace.pl')
| -rw-r--r-- | devtools/bin/srgb_colorspace.pl | 451 |
1 files changed, 451 insertions, 0 deletions
diff --git a/devtools/bin/srgb_colorspace.pl b/devtools/bin/srgb_colorspace.pl new file mode 100644 index 0000000..3c5404c --- /dev/null +++ b/devtools/bin/srgb_colorspace.pl @@ -0,0 +1,451 @@ + +# +# Arguments parsing +# + +local $script = $0; + +while ( 1 ) +{ + local $arg = shift; + if ( $arg =~ /-catsrgb1/i ) + { goto RUN_CAT_SRGB_1; } + if ( $arg =~ /-safecat/i ) + { goto RUN_SAFE_CAT; } + if ( $arg =~ /-delaywrite/i ) + { goto RUN_DELAY_WRITE; } + if ( $arg =~ /-processvmts/i ) + { goto RUN_PROCESS_VMTS; } + + # default mode - forward to processvmts: + # exit system( "dir" ); + exit system( "dir /s /b *.vmt | perl $script -processvmts" ); +} + + + + +RUN_CAT_SRGB_1: +# +# ----------- Adding "srgb 1" to options list -------- +# + +local $bAlreadyHasSrgb1 = 0; +while ( <> ) +{ + local $line = $_; + print $line; + $bAlreadyHasSrgb1 = 1 if $line =~ /srgb(.*)1/i; +} +print "\nsrgb 1\n" if !$bAlreadyHasSrgb1; +exit 0; + + + +RUN_DELAY_WRITE: +# +# ----------- Delay write to a file (essentially delayed shell redirection) ---- +# +local *fileptr; +local $filename = shift; + +local @lines; +while ( <> ) { push( @lines, $_ ); } + +open( fileptr, ">$filename" ); +foreach ( @lines ) { print fileptr $_ ; } +close( fileptr ); + +exit 0; + + + +RUN_SAFE_CAT: +# +# ----------- Cat of a non-existing file will succeed ---- +# +local *fileptr; +local $filename = shift; + +exit 1 if !open( fileptr, "<$filename" ); +while ( <fileptr> ) { print $_ ; } +close( fileptr ); + +exit 0; + + + + +RUN_PROCESS_VMTS: +# +# ----------- Processing the list of vmts ------------ +# + + +# +# Lookup array of directories under which to search for +# textures when resolving texture paths from vmt. +# +local @textureslookup = ( +# "u:/data/content/tf/", +# "u:/data/content/portal/", + +# "u:/data/content/ep2/", +# "u:/data/content/episodic/", + "u:/data/content/hl2/", +); + +# +# Mapping of shaders that require srgb conversion for +# basetextures. Entries listed lowercase, mapped to 1. +# +local %srgbshaders = ( + vertexlitgeneric => 1, + lightmappedgeneric => 1, + unlitgeneric => 1, + eyerefract => 1, + portalrefract => 1, + aftershock => 1, + sky => 1, + lightmappedreflective => 1, + portalstaticoverlay => 1, + particlesphere => 1, + shatteredglass => 1, + sprite => 1, + spritecard => 1, + teeth => 1, + treeleaf => 1, + vortwarp => 1, + water => 1, + windowimposter => 1, + worldtwotextureblend => 1, + worldvertexalpha => 1, +); + +# +# Mapping of variables that we will be looking for. +# +local %shadervarscheck = ( + basetexture => 1, + basetexture2 => 1, + basetexture3 => 1, + basetexture4 => 1, + envmap => 1, + iris => 1, + ambientoccltexture => 1, + refracttinttexture => 1, + albedo => 1, + compress => 1, + stretch => 1, + emissiveblendbasetexture => 1, + emissiveblendtexture => 1, + fleshinteriortexture => 1, + fleshbordertexture1d => 1, + fleshsubsurfacetexture => 1, + fleshcubetexture => 1, + texture2 => 1, + hdrcompressedtexture => 1, + hdrcompressedtexture0 => 1, + hdrcompressedtexture1 => 1, + hdrcompressedtexture2 => 1, + portalcolortexture => 1, + monitorscreen => 1, + staticblendtexture => 1, + refracttexture => 1, + reflecttexture => 1, +); + +# +# After parsing the list of vmt files contains a map of +# texture names as keys to the list of two elements: +# [0] +# 0: texture is non-srgb +# 1: texture is srgb and needs conversion +# -1: texture is ambiguous +# [1] +# list of vmts referring to the texture +# +local %textures2convert; + + +# +# Parse our list of vmt files +# Generate the list with "dir /s /b *.vmt" +# +while ( <> ) +{ + + local $fname = $_; + $fname =~ s/^\s*(.*)\s*$/$1/; + $fname =~ s/\\/\//g; +# print "-" . $fname . "-\n"; + + # Open the file + local *vmtfileptr; + open( vmtfileptr, "<$fname" ) || die; + + local $line; + local $shadername; + local %basetexture; + local $basetexture_real; + local $basetexture_blacklisted = 0; + + # Find shadername and textures + while ( $line = <vmtfileptr> ) + { + $line =~ s/^\s*(.*)\s*$/$1/; + $line = lc( $line ); + + if ( $. == 1 ) + { + $shadername = $line; + $shadername =~ s/\"//g; + } + + while ( ( $varname, undef ) = each %shadervarscheck ) + { + next if $line !~ /^\s*["]?\$$varname["]?\s+(.*)$/i; + + $line = $1; + if ( $line =~ /^\"([^\"])*\"(.*)$/ ) { + $line =~ s/^\"([^\"]*)\"(.*)$/$1/; + } else { + $line =~ s/^(\S*)(.*)$/$1/; + } + $line =~ s/^\s*(.*)\s*$/$1/; + $line =~ s/\\/\//g; + + next if $line =~ /^\_rt/i; + + $basetexture{ $line } = 1; + $basetexture_real = $line if $varname =~ /^basetexture$/i; + last; + } + + # blacklist stuff + $basetexture_blacklisted = 1 if $line =~ /^\s*["]?\$extractgreenalpha["]?\s*(.*)$/i; + print ">>> $fname blacklisted by >>> $line >>>\n" if $line =~ /^\s*["]?\$extractgreenalpha["]?\s*(.*)$/i; + } + + delete $basetexture{ $basetexture_real } if $basetexture_blacklisted; + print ">>> blacklisted texture: $basetexture_real .\n" if $basetexture_blacklisted; + delete $basetexture{ "env_cubemap" }; + + close vmtfileptr; + + # Print the shader and the base texture +# print "\tshader = " . $shadername . "\n"; +# foreach ( keys %basetexture ) { print "\ttexture = " . $_ . "\n" }; + + # If the texture needs a conversion stick it into the map + local $isSrgb = 1; #--shadercheck--( exists $srgbshaders{ $shadername } ? 1 : 0 ); + + foreach ( keys %basetexture ) + { + local $basetexture = $_; + if ( exists $textures2convert{ $basetexture } ) + { + # Check for validity + $isSrgb = -1 if $textures2convert{ $basetexture }->[0] != $isSrgb; + } + else + { + $textures2convert{ $basetexture } = [ $isSrgb, [] ]; + } + + $textures2convert{ $basetexture }->[0] = $isSrgb; + push( @{ $textures2convert{ $basetexture }->[1] }, $fname ); + } + +} + + +# +# Now walk over the accumulated textures and establish the srgb mapping +# +local @failedtextures; +while ( ( $basetexture, $value ) = each %textures2convert ) +{ + + local $isSrgb = $value->[0]; + + if ( -1 == $isSrgb ) + { + print "Warning: Ambiguity for "; + print "$basetexture from "; + foreach ( @{ $value->[1] } ) { print " $_"; }; + print "!\n"; + } + + next if 1 != $isSrgb; + + # + # Need to convert this texture + # + local $res = ConvertTexture( $basetexture ); + push( @failedtextures, $basetexture ) if !$res; + +} + +# Dump failed textures +if ( $#failedtextures > 0 ) +{ + print "\n---- errors ----\n"; + foreach ( @failedtextures ) + { + local $basetexture = $_; + print "ERROR: $basetexture in "; + foreach ( @{ $textures2convert{ $basetexture }->[1] } ) { print " $_"; } + print ";\n"; + } + print "---- end ----\n"; +} + + +# +# Converts a texture. +# Returns 1 for txt, 2 for psd, 3 for newly created txt. +# Returns 0 when nothing found. +# +sub ConvertTexture +{ + + local $basetexture = shift; + local $result = 0; + print "-- $basetexture ... "; + + foreach ( @textureslookup ) + { + # Try to open the txt file + local $txpath = $_ . "materialsrc/" . $basetexture; + if ( -f "$txpath.txt" || -f "$txpath.tga" ) + { + # Check it out + print "txt, p4 ... "; + `p4 edit "$txpath.txt" >nul 2>&1`; + `p4 lock "$txpath.txt" >nul 2>&1`; + + `perl $script -safecat "$txpath.txt" | perl $script -catsrgb1 | perl $script -delaywrite "$txpath.txt"`; + + `p4 add "$txpath.txt" >nul 2>&1` if -f "$txpath.txt"; + + # Also patch the VTF + $txpath =~ s,/content/,/game/,; + $txpath =~ s,/materialsrc/,/materials/,; + #PatchVtfFile( "$txpath.vtf" ); + + print "done ... "; + ++ $result; + } + if ( -f "$txpath.psd" ) + { + # Check it out + print "psd, p4 ... "; + `p4 edit "$txpath.psd" >nul 2>&1`; + `p4 lock "$txpath.psd" >nul 2>&1`; + + `psdinfo -read "$txpath.psd" | perl $script -catsrgb1 | psdinfo -write "$txpath.psd"`; + + `p4 add "$txpath.psd" >nul 2>&1`; + + # Also patch the VTF + $txpath =~ s,/content/,/game/,; + $txpath =~ s,/materialsrc/,/materials/,; + #PatchVtfFile( "$txpath.vtf" ); + + print "done ... "; + ++ $result; + } + } + + foreach ( @textureslookup ) + { + # Try to find the vtf file + local $txpath = $_ . "materials/" . $basetexture; + $txpath =~ s,/content/,/game/,i; + if ( -f "$txpath.vtf" ) + { + if ( !$result ) + { + # Create the text file then + print "src missing ... "; + $txpath =~ s,/game/,/content/,,i; + $txpath =~ s,/materials/,/materialsrc/,; + + `p4 edit "$txpath.txt" >nul 2>&1`; + `p4 lock "$txpath.txt" >nul 2>&1`; + + `perl $script -safecat "$txpath.txt" | perl $script -catsrgb1 | perl $script -delaywrite "$txpath.txt"`; + + `p4 add "$txpath.txt" >nul 2>&1` if -f "$txpath.txt"; + + # Also patch the VTF + $txpath =~ s,/content/,/game/,; + $txpath =~ s,/materialsrc/,/materials/,; + } + PatchVtfFile( "$txpath.vtf" ); + + print "done ... "; + ++ $result; + } + } + + if ( !$result ) + { + print "ERROR: not found.\n"; + } + else + { + print "ok.\n"; + } + return $result; + +} + +exit 0; + + +RUN_PATCH_VTF: +# +# ----------- Patch a VTF file -------- +# + +local $filename = shift; +exit PatchVtfFile( $filename ); + +sub PatchVtfFile +{ + + local *fileptr; + local $filename = shift; + local $vtfFlags; + + print "vtf, p4 ... "; + `p4 edit "$filename" >nul 2>&1`; + `p4 lock "$filename" >nul 2>&1`; + + if ( !open( fileptr, "+<$filename" ) ) + { + print "VTF missing ... "; + return 1; + } + binmode( fileptr ); + + seek( fileptr, 5 * 4, 0 ); + read( fileptr, $vtfFlags, 4 ); + $vtfFlags = unpack( "I", $vtfFlags ); + + # adding SRGB flag + $vtfFlags = $vtfFlags | 0x00000040; # mask or + + seek( fileptr, 5 * 4, 0 ); + print fileptr pack( "I", $vtfFlags ); + + close( fileptr ); + + print "vtf ok ... "; + return 0; + +} + + |