--- deliantra/server/utils/cfutil.in 2012/01/04 02:48:57 1.119 +++ deliantra/server/utils/cfutil.in 2017/01/11 11:39:02 1.126 @@ -2,23 +2,23 @@ # # This file is part of Deliantra, the Roguelike Realtime MMORPG. -# +# # Copyright (©) 2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team -# +# # Deliantra is free software: you can redistribute it and/or modify it under # the terms of the Affero GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the Affero GNU General Public License # and the GNU General Public License along with this program. If not, see # . -# +# # The authors can be reached via e-mail to # @@ -223,11 +223,19 @@ our @c_png; - sub commit_png($$$$) { - my ($stem, $name, $data, $T) = @_; + # texture catalog size, in 64x64 tiles + sub TC_W() { 1024 / 64 } + sub TC_H() { 1024 / 64 } + + our @TC = ([]); # texture catalogs + + sub commit_png($$$$$$) { + my ($stem, $name, $data, $T, $w, $h) = @_; - $FACEINFO{$name}{"stem"} = substr $stem, 1 + length $PATH; + $FACEINFO{$name}{stem} = substr $stem, 1 + length $PATH; $FACEINFO{$name}{"data$T"} = $data; + $FACEINFO{$name}{w} = $w; + $FACEINFO{$name}{h} = $h; } sub process_png { @@ -349,9 +357,9 @@ } } - system "convert -depth 8 $SRC rgba:-" + system "$CONVERT -depth 8 $SRC rgba:-" . "| $exec_prefix/bin/cfhq2xa $w $h 0" - . "| convert -depth 8 -size ".($w * 2)."x".($h * 2)." rgba:- $CROP $QUANTIZE -quality 00 png32:\Q$other\E~" + . "| $CONVERT -depth 8 -size ".($w * 2)."x".($h * 2)." rgba:- $CROP $QUANTIZE -quality 00 png32:\Q$other\E~" and die "convert/cfhq2xa pipeline error: status $? ($!)"; optipng "$other~"; rename "$other~", $other; @@ -367,7 +375,7 @@ make_file $path, $other, sub { fork_exec { - system "convert png:\Q$path\E -geometry 50% -filter lanczos $QUANTIZE -quality 00 png32:\Q$other\E~"; + system "$CONVERT png:\Q$path\E -geometry 50% -filter lanczos $QUANTIZE -quality 00 png32:\Q$other\E~"; optipng "$other~"; # reduce smoothfaces >10000 bytes @@ -447,7 +455,7 @@ aio_load $dpath, my $png; IO::AIO::aio_unlink $dpath unless $CACHE; - commit_png "$dir/$type:$face", "$type:$face", $png, $T; + commit_png "$dir/$type:$face", "$type:$face", $png, $T, 1, 1; } # split all bigfaces, but avoid smoothfaces (*_S) @@ -502,11 +510,11 @@ die "$path: unable to read tile +$x+$y, aborting.\n"; } IO::AIO::aio_unlink $file unless $CACHE; - commit_png $stem, $x|$y ? "$face+$x+$y" : $face, $tile, $T; + commit_png $stem, $x|$y ? "$face+$x+$y" : $face, $tile, $T, 1, 1; } } else { # use as-is (either small, use smooth) - commit_png $stem, $face, $png, $T; + commit_png $stem, $face, $png, $T, $w / $T, $h / $T; } IO::AIO::aio_unlink $path if $delete; @@ -763,10 +771,13 @@ %{ $meta->{$file} || {} }, }; - if ($meta->{license} =~ s/^#//) { + if (exists $meta->{license} && $meta->{license} =~ s/^#//) { # exists == avoid autovivification + # all these are acceptable for deliantra - if not specified, agpl 3+ is the default. $meta->{license} = ({ "pd" => "Public Domain", "gpl" => "GNU General Public License, version 3.0 or any later", + "2bsd" => "2-clause BSD/MIT style license", + "3bsd" => "3-clause BSD style license", "cc/by/2.0" => "Licensed under Creative Commons Attribution 2.0 http://creativecommons.org/licenses/by/2.0/", "cc/by/2.1" => "Licensed under Creative Commons Attribution 2.1 http://creativecommons.org/licenses/by/2.1/", "cc/by/2.5" => "Licensed under Creative Commons Attribution 2.5 http://creativecommons.org/licenses/by/2.5/", @@ -779,8 +790,7 @@ ($meta->{author} = $1) =~ s/_/ /g; } - $file =~ s/\.res$//; - $file =~ s/\.(ogg|wav|jpg|png)$//; + $file =~ s/\.(res|ogg|wav|jpg|png)$// unless $meta->{keep_suffix}; if ($file =~ s/\.plt$//) { $data = process_plt "$dir/$file", $data; @@ -799,11 +809,13 @@ substr $dir, 0, 1 + length $PATH, ""; - $RESOURCE{"$dir/$file"} = { + my %info = ( type => (exists $meta->{type} ? delete $meta->{type} : $type), data => $data, %$meta ? (meta => $meta) : (), - }; + ); + + $RESOURCE{"$dir/$file"} = \%info; } sub process_any { @@ -1036,7 +1048,10 @@ { print "processing facedata...\n" if $VERBOSE; - while (my ($k, $v) = each %FACEINFO) { + + for my $k (sort keys %FACEINFO) { + my $v = $FACEINFO{$k}; + length $v->{data32} or warn "ERROR: face '$k' has no png32 - this will not work.\n"; length $v->{data64} or warn "ERROR: face '$k' has no png64 - this will not work.\n"; @@ -1050,12 +1065,53 @@ $v->{visibility} // warn "ERROR: face '$k' has no visibility info - missing faceinfo entry?\n"; $v->{magicmap} // warn "ERROR: face '$k' has no foreground colour - missing faceinfo entry?\n"; - delete @$v{qw(arc stem derive)}; # not used by the server + if (0 && $v->{w} == 1 && $v->{h} == 1) { # texture catalogs + my $id = @TC; + my $n = @{ $TC[-1] }; + my $x = $n % TC_W; + my $y = int $n / TC_W; + + push @{ $TC[-1] }, [$v, $x, $y]; + + $v->{tc} = [$id, $x, $y]; + + push @TC, [] if $n == TC_W * TC_H - 1; # start new texture if full + } + + delete @$v{qw(w h arc stem derive)}; # not used by the server + } + +if (0) { #d# texture catalogs + print "creating texture catalogs...\n" if $VERBOSE; + + for my $id (0 .. $#TC) { + my $tc = $TC[$id]; + + my $cmd = "$CONVERT -depth 8 -size " . (TC_W * 64) . "x" . (TC_H * 64) . " xc:transparent"; + my $idx = "a"; + + for (@$tc) { + my $path = "$TMPDIR/tc" . $idx++; + + open my $fh, ">:perlio", $path + or die "$path: $!"; + syswrite $fh, $_->[0]{data64}; + + my $x = $_->[1] * 64; + my $y = $_->[2] * 64; + + $cmd .= " png:\Q$path\E -geometry +$x+$y -composite"; + } + + system "$cmd png:\Q$TMPDIR/tc$id\E"; + optipng "$TMPDIR/tc$id"; } +} print "processing resources...\n" if $VERBOSE; my $enc = JSON::XS->new->utf8->canonical->relaxed; - while (my ($k, $v) = each %RESOURCE) { + for my $k (sort keys %RESOURCE) { + my $v = $RESOURCE{$k}; if ($v->{meta} && $v->{meta}{datadir}) { delete $RESOURCE{$k}; @@ -1084,14 +1140,45 @@ } } - printf "writing facedata (%d faces, %d anims, %d resources)...\n", + printf "writing facedata...\n" if $VERBOSE; + + { + open my $fh, ">:perlio", "$DATADIR/facedata~" + or die "$DATADIR/facedata~: $!"; + + print $fh "FACEDATA"; + my $fofs = 8; + + my $put = sub { + my $len = length $_[0]; + my $ofs = $fofs; + + print $fh $_[0]; + $fofs += $len; + + ($len, $ofs) + }; + + for (values %FACEINFO) { + ($_->{size32}, $_->{fofs32}) = $put->(delete $_->{data32}); + ($_->{size64}, $_->{fofs64}) = $put->(delete $_->{data64}); + } + + for (values %RESOURCE) { + ($_->{size}, $_->{fofs}) = $put->(delete $_->{data}); + } + + close $fh; + } + + printf "writing faceinfo (%d faces, %d anims, %d resources)...\n", scalar keys %FACEINFO, scalar keys %ANIMINFO, scalar keys %RESOURCE if $VERBOSE; - open my $fh, ">:perlio", "$DATADIR/facedata~" - or die "$DATADIR/facedata~: $!"; + open my $fh, ">:perlio", "$DATADIR/faceinfo~" + or die "$DATADIR/faceinfo~: $!"; print $fh nfreeze { version => 2, @@ -1103,7 +1190,7 @@ print "committing files...\n" if $VERBOSE; - for (qw(archetypes facedata treasures), @COMMIT) { + for (qw(archetypes faceinfo facedata treasures), @COMMIT) { chmod 0644, "$DATADIR/$_~"; rename "$DATADIR/$_~", "$DATADIR/$_" or die "$DATADIR/$_: $!";