#!/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 " : : "; }