You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
451 lines
9.5 KiB
451 lines
9.5 KiB
|
|
# |
|
# 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; |
|
|
|
} |
|
|
|
|
|
|