X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=misc%2Ftools%2Fbsptool.pl;h=63bc38931f5c2c82804dc095aa35ccc9f3814118;hb=f19bb65e08e05c1e211610e7884394267b0757f5;hp=84f23233aa388f3f91c86422623f394f6db5dc57;hpb=e5832bf2ecac60a672a29c85cd8dec341a215e1c;p=xonotic%2Fxonotic.git diff --git a/misc/tools/bsptool.pl b/misc/tools/bsptool.pl index 84f23233..63bc3893 100755 --- a/misc/tools/bsptool.pl +++ b/misc/tools/bsptool.pl @@ -6,6 +6,25 @@ use Image::Magick; use POSIX qw/floor ceil/; my @lumpname = qw/entities textures planes nodes leafs leaffaces leafbrushes models brushes brushsides vertices triangles effects faces lightmaps lightgrid pvs advertisements/; +my %lumpsize = ( + textures => 72, + planes => 16, + nodes => 36, + leafs => 48, + leaffaces => 4, + leafbrushes => 4, + models => 40, + brushes => 12, + brushsides => 8, + vertices => 44, + triangles => 4, + effects => 72, + faces => 104, + lightmaps => 49152, + lightgrid => 8, + advertisements => 128 +); + my %lumpid = map { $lumpname[$_] => $_ } 0..@lumpname-1; my $msg = ""; my @bsp; @@ -22,6 +41,7 @@ Operations are: Information requests: -i print info about the BSP file -xlumpname extract a lump (see -i) + -S list used shaders Changes: -dlumpname delete a lump (see -i) @@ -32,6 +52,7 @@ Operations are: -lpng externalize the lightmaps as PNG -ltga externalize the lightmaps as TGA -mMESSAGE set the BSP file comment message + -Sfrom=to replace a texture (shader) by name (already replaced shaders are not touched) Save commands: -o actually apply the changes to the BSP @@ -93,7 +114,11 @@ sub DecodeLump($@) $spec .= "$2$3 "; my $f = $1; my $n = $3; - if($n eq '') + if($2 eq 'a') + { + push @decoders, sub { ($item->{$f} = $data[$idx++]) =~ s/\0//g; }; + } + elsif($n eq '') { push @decoders, sub { $item->{$f} = $data[$idx++]; }; } @@ -141,7 +166,11 @@ sub EncodeLump($@) my $spec = "$2$3"; my $f = $1; my $n = $3; - if($n eq '') + if($2 eq 'a') + { + push @encoders, sub { $data .= pack $spec, $item->{$f}; }; + } + elsif($n eq '') { push @encoders, sub { $data .= pack $spec, $item->{$f}; }; } @@ -218,13 +247,19 @@ for(@ARGV) { if(/^-i$/) # info { - my $total = 17 * 8 + 8 + length($msg); + my $msgalign = [0, 3, 2, 1]->[length($msg) % 4]; + my $total = 17 * 8 + 8 + length($msg) + $msgalign; my $max = 0; for(0..@bsp-1) { my $nl = length $bsp[$_]->[2]; - $total += $nl; - print "BSP lump $_ ($lumpname[$_]): offset $bsp[$_]->[0] length $bsp[$_]->[1] newlength $nl\n"; + my $align = [0, 3, 2, 1]->[$nl % 4]; + $total += $nl + $align; + my $l = $bsp[$_]->[1]; + my $szi = $lumpsize{$lumpname[$_]}; + my $li = $szi ? " (" . ($l / $szi) . ")" : ""; + my $nli = $szi ? " (" . ($nl / $szi) . ")" : ""; + print "BSP lump $_ ($lumpname[$_]): offset $bsp[$_]->[0] length $l$li newlength $nl$nli\n"; my $endpos = $bsp[$_]->[0] + $bsp[$_]->[1]; $max = $endpos if $max < $endpos; } @@ -479,6 +514,30 @@ for(@ARGV) unless defined $id; print $bsp[$id]->[2]; } + elsif(/^-S(.*)=(.*)$/) + { + my $from = $1; + my $to = $2; + our @replaced = (); + my @l = DecodeLump $bsp[$lumpid{textures}]->[2], qw/name=a64 flags=V contents=V/; + for(0..@l-1) + { + next if $replaced[$_]; + if($l[$_]->{name} eq $from) + { + $replaced[$_] = 1; + $l[$_]->{name} = $to; + } + } + $bsp[$lumpid{textures}]->[2] = EncodeLump \@l, qw/name=a64 flags=V contents=V/; + } + elsif(/^-S$/) + { + for(DecodeLump $bsp[$lumpid{textures}]->[2], qw/name=a64 flags=V contents=V/) + { + print "$_->{name}\n"; + } + } elsif(/^-o(.+)?$/) # write the final BSP file { my $outfile = $1; @@ -487,18 +546,23 @@ for(@ARGV) open my $fh, ">", $outfile or die "$outfile: $!"; print $fh $header; - my $pos = 17 * 8 + tell($fh) + length $msg; + my $msgalign = [0, 3, 2, 1]->[length($msg) % 4]; + my $pos = 17 * 8 + tell($fh) + length($msg) + $msgalign; for(@bsp) { + my $align = [0, 3, 2, 1]->[length($_->[2]) % 4]; $_->[0] = $pos; $_->[1] = length $_->[2]; - $pos += $_->[1]; + $pos += $_->[1] + $align; print $fh pack "VV", $_->[0], $_->[1]; } print $fh $msg; + print $fh "\x00" x $msgalign; for(@bsp) { + my $align = [0, 3, 2, 1]->[length($_->[2]) % 4]; print $fh $_->[2]; + print $fh "\x00" x $align; } close $fh; print STDERR "Wrote $outfile\n";