#!/usr/bin/perl -w use strict; use constant BUFFER_SIZE => 128; if( $#ARGV != 0 ) { die "$0 \n"; } my $line_count = $ARGV[0]; my $mode = $line_count % 2; my $pi = atan2(0, -1); my @buffer = (); for(my $i = 0; $i < BUFFER_SIZE; $i++) { push @buffer, (("X" x 79) . "\n"); } my $head = 0; my $tail = 40; my $char = 0; my $last_x = 40; my $last_y = 80; for(; $line_count > 0; $line_count--) { $buffer[$tail] = ("X" x 79) . "\n"; $tail = ($tail + 1) % BUFFER_SIZE; $head != $tail or die; # Generate star my $cx = rand(70) + 5; my $distance = sqrt(($cx - $last_x) * ($cx - $last_x) + $last_y * $last_y); if( $last_y > 30 && $distance > 40 ) { my $size0 = 1 + rand(2); my $size1 = 12 - $size0 + rand(8); my $phase = rand(2 * $pi); my $v0 = 0.5; my $v1 = 0.5; if( $mode ) { $size0 = 17 + rand(5); $size1 = 0; $v0 = 0.2; $v1 = 0.4; } for(my $ta = 0; $ta < 10 * $pi; $ta += 0.05) { my $r = $size0 + $size1 + $size1 * 0.5 * sin($ta + $phase); for(my $tr = 0; $tr < $r; $tr += 0.1) { my $x = $cx + $tr * cos($ta / 5); my $dy = $tr * sin($ta / 5); my $y = ($tail + BUFFER_SIZE - 20) + ($dy > 0 ? $v0 * $dy : $v1 * $dy); $y = int($y + 0.5) % BUFFER_SIZE; $x = int($x + 0.5); if( $x >= 0 && $x < length($buffer[$y]) ) { substr($buffer[int($y + 0.5)], int($x + 0.5), 1) = ' '; } } } $last_x = $cx; $last_y = 0; if( $mode ) { $cx += rand($size0) - $size0 / 2; my $y1 = int($tail + BUFFER_SIZE - 21) % BUFFER_SIZE; my $y2 = int($tail + BUFFER_SIZE - 22) % BUFFER_SIZE; if( $cx - 3 > 2 ) { substr($buffer[$y1], int($cx) - 3, 1) = '#'; substr($buffer[$y2], int($cx) - 3, 1) = '#'; } if( $cx + 2 < 77 ) { substr($buffer[$y1], int($cx) + 2, 1) = '#'; substr($buffer[$y2], int($cx) + 2, 1) = '#'; } } } else { $last_y += 2; } # Output text following template my $template = $buffer[$head]; $head = ($head + 1) % BUFFER_SIZE; foreach my $c (unpack 'C*', $template) { $c = chr($c); if( $c =~ /\s/s ) { print $c; } else { print chr($char + ord('a')); $char = ($char + 1) % 26; } } }