xonotic/misc/tools/xonotic-map-compiler
t0uYK8Ne c77d376384 Scale the map after the lightmap has been rendered
Fixes dark patches on maps that are scaled down.
2017-02-27 08:17:06 -08:00

317 lines
6.8 KiB
Perl
Executable File

#!/usr/bin/perl
use strict;
use warnings;
use POSIX;
use File::Temp;
# change these to match your system, or define them in ~/.xonotic-map-compiler
# (just copy paste this part to the file ~/.xonotic-map-compiler)
# Path to Xonotic (where the data directory is in)
our $XONOTICDIR = getcwd();
# Path to your q3map2 program. You find it in your GtkRadiant/install
# directory.
our $Q3MAP2 = getcwd() . '/netradiant/install/q3map2';
# General flags for q3map2 (for example -threads 4)
our $Q3MAP2FLAGS = '-fs_forbiddenpath xonotic*-data*.pk3* -fs_forbiddenpath xonotic*-nexcompat*.pk3*';
# Default flags for the -bsp stage
our $BSPFLAGS = '-meta -maxarea -samplesize 8 -mv 1000000 -mi 6000000';
# Default flags for the -vis stage
our $VISFLAGS = '';
# Default flags for the -light stage
our $LIGHTFLAGS = '-lightmapsize 1024 -lightmapsearchpower 4 -deluxe -patchshadows -randomsamples -samples 4 -fast -fastbounce -dirty -bouncegrid -fill';
# Default flags for the -minimap stage
our $MINIMAPFLAGS = '';
# Default order of commands
our $ORDER = 'vis,light,scale';
# end of user changable part
do "$ENV{HOME}/.xonotic-map-compiler";
sub Usage()
{
print <<EOF;
Usage:
$0 mapname [-bsp bspflags...] [-vis visflags...] [-light lightflags...] [-minimap minimapflags]
EOF
exit 1;
}
my $options =
{
bsp => [split /\s+/, $BSPFLAGS],
vis => [split /\s+/, $VISFLAGS],
light => [split /\s+/, $LIGHTFLAGS],
minimap => [split /\s+/, $MINIMAPFLAGS],
scale => [], # can't have defaults atm
order => [split /\s*,\s*/, $ORDER],
maps => [],
scalefactor => 1,
bsp_timeout => 0,
vis_timeout => 0,
light_timeout => 0,
minimap_timeout => 0,
scale_timeout => 0,
timeout_stealing => 0,
};
my $curmode = 'maps';
while(@ARGV)
{
$_ = shift @ARGV;
my $enterflags = undef;
if($_ eq '-bsp')
{
$enterflags = 'bsp';
}
elsif($_ eq '-vis')
{
$enterflags = 'vis';
}
elsif($_ eq '-light')
{
$enterflags = 'light';
}
elsif($_ eq '-minimap')
{
$enterflags = 'minimap';
}
elsif($_ eq '-map')
{
$curmode = 'maps';
}
elsif($_ eq '-scale')
{
$options->{scalefactor} = @ARGV ? shift(@ARGV) : 1;
$enterflags = 'scale';
}
elsif($_ eq '-novis')
{
$options->{vis} = undef;
}
elsif($_ eq '-nolight')
{
$options->{light} = undef;
}
elsif($_ eq '-nominimap')
{
$options->{minimap} = undef;
}
elsif($_ eq '-bsp_timeout')
{
$options->{bsp_timeout} = shift @ARGV;
}
elsif($_ eq '-vis_timeout')
{
$options->{vis_timeout} = shift @ARGV;
}
elsif($_ eq '-light_timeout')
{
$options->{light_timeout} = shift @ARGV;
}
elsif($_ eq '-minimap_timeout')
{
$options->{minimap_timeout} = shift @ARGV;
}
elsif($_ eq '-scale_timeout')
{
$options->{scale_timeout} = shift @ARGV;
}
elsif($_ eq '-timeout_stealing')
{
$options->{timeout_stealing} = shift @ARGV;
}
elsif($_ eq '-order')
{
$options->{order} = [split /\s*,\s*/, shift @ARGV];
}
elsif($_ eq '-sRGB')
{
push @{$options->{bsp}}, "-sRGBtex", "-sRGBcolor";
push @{$options->{light}}, "-sRGBtex", "-sRGBcolor", "-sRGBlight"
if defined $options->{light};
}
elsif($_ eq '-nosRGB')
{
push @{$options->{bsp}}, "-nosRGBtex", "-nosRGBcolor";
push @{$options->{light}}, "-nosRGBtex", "-nosRGBcolor", "-nosRGBlight"
if defined $options->{light};
}
elsif($_ =~ /^--no(-.*)/)
{
if($curmode eq 'maps')
{
$curmode = 'bsp';
}
my $flag = $1;
@{$options->{$curmode}} = grep { (($_ eq $flag) ... /^-/) !~ /^[0-9]+$/ } @{$options->{$curmode}};
# so, e.g. --no-samplesize removes "-samplesize" and a following "3"
}
elsif($_ =~ /^-(-.*)/)
{
if($curmode eq 'maps')
{
$curmode = 'bsp';
}
push @{$options->{$curmode}}, $1;
}
elsif($_ =~ /^-/ and $curmode eq 'maps')
{
$curmode = 'bsp';
push @{$options->{$curmode}}, $_;
}
else
{
push @{$options->{$curmode}}, $_;
}
if(defined $enterflags)
{
$curmode = $enterflags;
if($ARGV[0] eq '+')
{
shift @ARGV;
}
else
{
$options->{$curmode} = [];
}
}
}
my $linkdir = File::Temp::tempdir("xonotic-map-compiler.XXXXXX", TMPDIR => 1, CLEANUP => 1);
my $starttime = time;
my $endtime = time;
sub q3map2(@)
{
my $mode = $_[0];
my $timeout = undef;
$timeout = $options->{bsp_timeout} if $mode eq '-bsp';
$timeout = $options->{vis_timeout} if $mode eq '-vis';
$timeout = $options->{light_timeout} if $mode eq '-light';
$timeout = $options->{minimap_timeout} if $mode eq '-minimap';
$timeout = $options->{scale_timeout} if $mode eq '-scale';
die "Invalid call: not a standard q3map2 stage" if not defined $timeout;
$endtime += $timeout;
my $stolen_timeout = $endtime - time;
if ($stolen_timeout > $timeout)
{
$timeout += ($stolen_timeout - $timeout) * $options->{timeout_stealing};
}
my @args = ($Q3MAP2, split(/\s+/, $Q3MAP2FLAGS), '-game', 'xonotic', '-fs_basepath', $XONOTICDIR, '-fs_basepath', $linkdir, '-v', @_);
print "\$ @args\n";
print "Using timeout: $timeout\n";
defined(my $pid = fork())
or die "fork: $!";
if($pid) # parent
{
local $SIG{ALRM} = sub { warn "SIGALRM caught\n"; kill TERM => $pid; };
alarm $timeout
if $timeout;
if(waitpid($pid, 0) != $pid)
{
die "waitpid: did not return our child process $pid: $!";
}
alarm 0;
return ($? == 0);
}
else # child
{
exec @args
or die "exec: $!";
}
}
if ($options->{scalefactor} =~ /^([0-9.]+):([0-9.]+)$/)
{
die "Two-scale isn't supported"
if $1 != 1 and $2 != 1;
$options->{scalefactor} = $1
if $2 == 1;
$options->{scalefactor} = $2
if $1 == 1;
}
my $origcwd = getcwd();
for my $m(@{$options->{maps}})
{
chdir $origcwd
or die "chdir $origcwd: $!";
if($m =~ s!(.*)/!!)
{
my $predir = $1;
chdir $predir
or die "chdir $predir: $!";
}
symlink getcwd() . "/..", "$linkdir/data"
or die "symlink $linkdir/data: $!";
$m =~ s/\.(?:map|bsp)$//;
# never hurts, may help with rtlights
unshift @{$options->{bsp}}, "-keeplights";
local $SIG{INT} = sub
{
print "SIGINT caught, cleaning up...\n";
exit 0;
};
unlink <$m/lm_*>; # delete old external lightmaps
q3map2 '-bsp', @{$options->{bsp}}, "$m.map"
or die "-bsp: $?";
my @o = @{$options->{order}};
push @o, qw/vis scale light/;
my %o = ();
for(@o)
{
next if $o{$_}++;
if($_ eq 'light')
{
if(defined $options->{light})
{
q3map2 '-light', @{$options->{light}}, "$m.map"
or die "-light: $?";
}
}
if($_ eq 'vis')
{
if(defined $options->{vis})
{
q3map2 '-vis', @{$options->{vis}}, "$m.map"
or die "-vis: $?";
}
}
if($_ eq 'scale')
{
if ($options->{scalefactor} != 1)
{
q3map2 '-scale', @{$options->{scale}}, $options->{scalefactor}, "$m.bsp"
or die "-scale: $?";
rename "${m}_s.bsp", "$m.bsp"
or die "rename ${m}_s.bsp $m.bsp: $!";
}
}
}
if(defined $options->{minimap})
{
q3map2 '-minimap', @{$options->{minimap}}, "$m.map"
or die "-minimap: $?";
}
unlink "$m.srf";
unlink "$m.prt";
}