bcd_clock
#!/usr/bin/perl -w
#
# bcd_clock -- BCD clock
# for a hardware implementation:
# http://www.thinkgeek.com/homeoffice/lights/59e0/
#
use strict;
use Term::ReadKey;
use Term::ANSIScreen qw/:color :constants :cursor :screen/;
use integer;
#
# signal handlers
#
$SIG{INT} = \&sighndl;
$SIG{TERM} = \&sighndl;
$SIG{CHLD} = 'IGNORE';
my $key; # key pressed
my $sigtermed; # signal terminated
my @digit_in_col; # digit to be encoded in screen column
my @led; # three-d array of boolean on/off for each LED
my $hr; # current hour
my $min; # current minute
my $sec; # current second
my $row; # screen row coordinate
my $col; # screen column coordinate
my $prev; # index of previous LED map
my $curr; # index of current LED map
my $n; # temporary variable
my $on; # current LED on?
$| = 1;
screeninit();
ReadMode 4; # raw
$curr = 0;
#
# avoiding uninitialized value warnings...
#
for ( $col = 2; $col <= 22; $col += 4 ) {
for ( $row = 7; $row >= 1; $row -= 2 ) {
$led[$curr][$row][$col] = 0;
}
}
while ( !$sigtermed ) {
#
# switch frames
#
$curr = 1 - $curr;
$prev = 1 - $curr;
( $sec, $min, $hr ) = localtime();
#
# We could get fancy with all sorts of mappings
# between time values and LED screen locations. Let's not.
#
$digit_in_col[2] = $hr / 10;
$digit_in_col[6] = $hr % 10;
$digit_in_col[10] = $min / 10;
$digit_in_col[14] = $min % 10;
$digit_in_col[18] = $sec / 10;
$digit_in_col[22] = $sec % 10;
for ( $col = 2; $col <= 22; $col += 4 ) {
locate( 9, $col );
$n = $digit_in_col[$col];
print $n;
for ( $row = 7; $row >= 1; $row -= 2 ) {
$led[$curr][$row][$col] = $on = ( $n & 1 );
if ( $on != $led[$prev][$row][$col] ) {
locate( $row, $col );
print $on ? BLACK ON_RED " " : " ";
}
$n >>= 1;
}
}
locate( 1, 1 );
if ( defined( $key = ReadKey(-1) ) ) { # keypress!
last if ( $key eq "Q" || $key eq "q" );
}
sleep 1;
}
locate( 1, 1 );
cls;
ReadMode 0;
exit(0);
sub sighndl {
my ($sig) = @_;
$sigtermed = $sig;
}
sub screeninit {
$Term::ANSIScreen::AUTORESET = 1;
cls;
locate( 1, 1 );
print " ( ) ( ) ( )";
locate( 3, 1 );
print " ( ) ( ) ( ) ( ) ( )";
locate( 5, 1 );
print "( ) ( ) ( ) ( ) ( ) ( )";
locate( 7, 1 );
print "( ) ( ) ( ) ( ) ( ) ( )";
locate( 9, 1 );
print " : : ";
}