--- deliantra/server/utils/cfutil.in 2012/01/04 03:22:28 1.120 +++ deliantra/server/utils/cfutil.in 2012/10/29 22:50:10 1.121 @@ -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; @@ -1036,7 +1044,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,9 +1061,49 @@ $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) {