#!/usr/bin/perl -w
#
# I make weird shit when I'm bored.
# (C)2019 The Almighty Pegasus Epsilon <pegasus@pimpninjas.org>
# Distribute Unmodified - http://pegasus.pimpninjas.org/license
use strict;
use POSIX;
use IO::Handle;
use Math::Trig "pi", ":radial";
use v5.10;
select(((select STDOUT), $| = 1)[0]);
my $termios = POSIX::Termios->new();
$termios->getattr(fileno(STDIN));
my $lflag = $termios->getlflag();
my $vtime = $termios->getcc(VTIME);
my $vmin = $termios->getcc(VMIN);
sub raw {
$termios->setlflag($lflag & ~(ECHO | ECHOK | ICANON));
# non-blocking keyboard polling ftw
$termios->setcc(VTIME, 0);
$termios->setcc(VMIN, 0);
$termios->setattr(fileno(STDIN), TCSANOW);
}
sub cooked {
$termios->setlflag($lflag);
$termios->setcc(VTIME, $vtime);
$termios->setcc(VMIN, $vmin);
$termios->setattr(fileno(STDIN), TCSANOW);
}
my $terminal = do {
require Term::Cap;
Tgetent Term::Cap { TERM => undef, OSPEED => $termios->getospeed };
};
END {
cooked();
$terminal->Tputs("ve", 0, \*STDOUT);
}
$SIG{TERM} = $SIG{INT} = sub { exit; };
$terminal->Tputs("cl", 0, \*STDOUT);
$terminal->Tputs("vi", 0, \*STDOUT);
raw();
use Term::ReadKey;
my ($cols, $rows, $max, $step);
$SIG{WINCH} = sub {
local @_ = GetTerminalSize();
($cols, $rows) = $#_ ? @_ : (80, 24);
$max = sqrt($cols ** 2 + $rows ** 2) * 1.1 / 2;
$step = $rows ** 1 * $cols ** 1 / 8192;
};
&{$SIG{WINCH}};
#say "data: ", join ",", $cols, $rows, $max, $step;
#sleep 2;
#__DATA__
my $thinness = 2.5;
my @bytes = split //, '#$%!:.' . (' ' x ($thinness * $max));
for (;;) {
for (my $r = 0; $max > $r; $r += $step) {
$terminal->Tgoto("cm", 0, 0, \*STDOUT);
for my $y (1..$rows) {
for my $x (1..$cols) {
# the hard way
#my ($cx, $cy) = ($x - $cols / 2, ($y - $rows / 2) * 31 / 16);
#my $theta = atan2($cy, $cx);
#my $dist = sin($theta) ? cos($theta) ? abs(sin($theta)) > abs(cos($theta)) ? $cy / sin($theta) : $cx / cos($theta) : $cy / sin($theta) : $cx / cos($theta);
# the easy way
my ($dist) = cartesian_to_cylindrical($x - $cols / 2, ($y - $rows / 2) * 31 / 16);
my $d = fabs($dist - $r);
print $bytes[int $d * $thinness];
}
}
STDOUT->flush();
exit if (sysread STDIN, my $k, 100);
select('', '', '', 1/60);
}
}