12 # int type = {projection type enum}
13 # float boundingradius
14 # int width = width of largest frame
15 # int height = height of largest frame
18 # int synctype = {ST_SYNC=0, ST_RAND=1}
22 # int type = {SPR_SINGLE=0, SPR_GROUP=1}
23 # if type == SPR_GROUP:
24 # int numframes_thisgroup
25 # for 1..numframes_thisgroup:
27 # for 1..numframes_thisgroup:
33 # width*height*4 bytes of image data, RGBA
35 my $magick = Image::Magick->new();
46 my ($spritestruct, $filename) = @_;
47 open my $fh, '>', $filename;
50 syswrite $fh, pack 'V', 32;
51 syswrite $fh, pack 'V', $spritestruct->{type};
53 my $radius_x = abs(abs($spritestruct->{x0}) > abs($spritestruct->{x1}) ? $spritestruct->{x0} : $spritestruct->{x1});
54 my $radius_y = abs(abs($spritestruct->{y0}) > abs($spritestruct->{y1}) ? $spritestruct->{y0} : $spritestruct->{y1});
56 syswrite $fh, pack 'f', sqrt($radius_x * $radius_x + $radius_y * $radius_y);
57 syswrite $fh, pack 'V', $spritestruct->{x1} - $spritestruct->{x0};
58 syswrite $fh, pack 'V', $spritestruct->{y1} - $spritestruct->{y0};
59 syswrite $fh, pack 'V', scalar @{$spritestruct->{groups}};
60 syswrite $fh, pack 'f', $spritestruct->{beamlength};
61 syswrite $fh, pack 'V', $spritestruct->{synctype};
63 for my $g(@{$spritestruct->{groups}})
69 syswrite $fh, pack 'V', 0;
74 syswrite $fh, pack 'V', 1;
75 syswrite $fh, pack 'V', scalar @$f;
76 syswrite $fh, pack 'f', $_->{interval} for @$f;
80 syswrite $fh, pack 'V', -$_->{orgx};
81 syswrite $fh, pack 'V', $_->{orgy};
82 syswrite $fh, pack 'V', $_->{width};
83 syswrite $fh, pack 'V', $_->{height};
84 syswrite $fh, $_->{data};
91 my ($type, $beamlength, $synctype) = @_;
94 beamlength => $beamlength,
95 synctype => $synctype,
117 sub spriteframe($$$$$)
119 my ($spritestruct, $imagefile, $orgx, $orgy, $interval) = @_;
120 checkmagick $magick->Read($imagefile);
121 my ($width, $height) = $magick->Get('columns', 'rows');
122 my $data = $magick->ImageToBlob(depth => 8, magick => 'RGBA');
124 if length $data != 4 * $width * $height;
125 my $g = ($spritestruct->{groups}->[-1]);
126 push @{$g->{frames}}, my $s = {};
127 $s->{width} = $width;
130 $s->{width} = $width;
131 $s->{height} = $height;
133 $s->{interval} = $interval;
137 my $x1 = $width - $orgx;
138 my $y1 = $height - $orgy;
140 $spritestruct->{x0} = $x0 if $width > $spritestruct->{x0};
141 $spritestruct->{y0} = $y0 if $width > $spritestruct->{y0};
142 $spritestruct->{x1} = $x1 if $width > $spritestruct->{x1};
143 $spritestruct->{y1} = $y1 if $width > $spritestruct->{y1};
148 my ($spritestruct) = @_;
149 push @{$spritestruct->{groups}}, my $g = {};
157 [-proj projectiontype]
161 -sprite filename.tga orgx orgy interval
162 [-sprite filename.tga orgx orgy interval [...]]
164 -sprite filename.tga orgx orgy interval
165 [-sprite filename.tga orgx orgy interval [...]] [...]]
169 my $proj = 2; # SPR_VP_PARALLEL
193 $outfile = shift @ARGV;
195 elsif($s eq '-group')
199 elsif($s eq '-sprite')
207 unshift @ARGV, '-sprite';
212 usage() unless defined $outfile;
214 my $spritestruct = spritestruct($proj, $beam, $synctype);
215 print "created sprite with projection $proj, beam length $beam, sync type $synctype\n";
217 spritegroup($spritestruct);
218 print " created sprite group\n";
227 my ($filename, $orgx, $orgy, $interval) = splice @ARGV, 0, 4;
228 usage() if not defined $interval;
229 spriteframe($spritestruct, $filename, $orgx, $orgy, $interval);
230 print " created sprite frame $filename, origin at $orgx|$orgy, interval $interval\n";
232 elsif($s eq '-group')
234 spritegroup($spritestruct);
235 print " created sprite group\n";
239 my ($orgx, $orgy, $interval) = splice @ARGV, 0, 3;
240 usage() if not defined $interval;
241 spriteframe($spritestruct, $s, $orgx, $orgy, $interval);
242 print " created sprite frame $s, origin at $orgx|$orgy, interval $interval\n";
246 writesprite($spritestruct, $outfile);
247 print "written to $outfile\n";