#! /home/xxxx/CitrusPerl/perl/bin/perl # LedPanelApp.pl - Application to draw a simulated LED Dot Matrix Style Display # # Based on a wxWidgets C++ application by Christian Gr�fe (info@mcs-soft.de) # Reimplemented in wxPerl by James M. Lynes, Jr # Last Modified: March 14, 2013 # # Led size can vary from about 3 on up to 10 or more # Led colors supported are: Red, Green, Blue, Yellow, Magenta, Cyan, Gray # Display can scroll Left, Right, Up, or Down # "Inverse video" is supported # 5x7 dot matrix style characters are used # # This test application displays 7 scrolling LED style panels # package main; use strict; use warnings; my $app = App->new(); $app->MainLoop; package App; use strict; use warnings; use base 'Wx::App'; sub OnInit { my $frame = Frame->new(); $frame->Show(1); } package Frame; use strict; use warnings; use Wx qw(:everything); use base qw(Wx::Frame); use Wx::Event qw(EVT_PAINT EVT_TIMER); use LedPanelDisplay; use Data::Dumper; sub new { my($self) = @_; # # Create Top Level Window # $self = $self->SUPER::new(undef, -1, "LedPanelApp1.pl", [0,0], [1020,425]); $self->SetBackgroundColour(wxBLUE); # # Create Seven Panels, One Led Display per Panel # $self->{LP1} = Wx::Panel->new($self, -1, [10,10], [1000,32], wxRAISED_BORDER); $self->{LP1}->SetBackgroundColour(wxBLACK); $self->{LP2} = Wx::Panel->new($self, -1, [10,48], [1000,40], wxRAISED_BORDER); $self->{LP2}->SetBackgroundColour(wxBLACK); $self->{LP3} = Wx::Panel->new($self, -1, [10,93], [1000,47], wxRAISED_BORDER); $self->{LP3}->SetBackgroundColour(wxBLACK); $self->{LP4} = Wx::Panel->new($self, -1, [10,145], [1000,54], wxRAISED_BORDER); $self->{LP4}->SetBackgroundColour(wxBLACK); $self->{LP5} = Wx::Panel->new($self, -1, [10,204], [1000,61], wxRAISED_BORDER); $self->{LP5}->SetBackgroundColour(wxBLACK); $self->{LP6} = Wx::Panel->new($self, -1, [10,270], [1000,68], wxRAISED_BORDER); $self->{LP6}->SetBackgroundColour(wxBLACK); $self->{LP7} = Wx::Panel->new($self, -1, [10,343], [1000,75], wxRAISED_BORDER); $self->{LP7}->SetBackgroundColour(wxBLACK); # # Create Seven Led Displays, Sizes 4 thru 10, Colors Red thru Gray, Assorted Text # my %colors = ( red => 0, green => 1, blue => 2, yellow => 3, magenta => 4, cyan => 5, gray => 6, ); $self->{led1} = LedPanelDisplay->new(width => 216, height =>7, ledsize => 4, id => "led1",); $self->{led1}->{message} = "LINE 1 ABCDEFGHIJKLM "; $self->{led1}->{pallet} = $colors{red}; $self->{led1}->{spacing} = 1; $self->{led1}->{scrolldirection} = "left"; $self->{led1}->{invert} = 1; LedPanelDisplay->Init($self->{led1}); $self->{led2} = LedPanelDisplay->new(width => 216, height =>7, ledsize => 5, id => "led2"); $self->{led2}->{message} = "LINE 2 NOPQRSTUVWXYZ "; $self->{led2}->{pallet} = $colors{green}; $self->{led2}->{scrolldirection} = "right"; $self->{led2}->{invert} = 1; $self->{led2}->{showinactives} = 0; LedPanelDisplay->Init($self->{led2}); $self->{led3} = LedPanelDisplay->new(width => 216, height =>7, ledsize => 6, id => "led3"); $self->{led3}->{message} = " LINE 3 abcdefghijklm "; $self->{led3}->{pallet} = $colors{blue}; $self->{led3}->{scrolldirection} = "up"; $self->{led3}->{showinactives} = 0; LedPanelDisplay->Init($self->{led3}); $self->{led4} = LedPanelDisplay->new(width => 216, height =>7, ledsize => 7, id => "led4"); $self->{led4}->{message} = "LINE 4 nopqrstuvwxyz "; $self->{led4}->{pallet} = $colors{yellow}; $self->{led4}->{scrolldirection} = "down"; LedPanelDisplay->Init($self->{led4}); $self->{led5} = LedPanelDisplay->new(width => 216, height =>7, ledsize => 8, id => "led5"); $self->{led5}->{message} = "LINE 5 !\"#\$%&()*+,-./:; "; $self->{led5}->{pallet} = $colors{magenta}; $self->{led5}->{scrolldirection} = "left"; LedPanelDisplay->Init($self->{led5}); $self->{led6} = LedPanelDisplay->new(width => 216, height =>7, ledsize => 9, id => "led6"); $self->{led6}->{message} = " LINE 6 <=>?@[]^_` "; $self->{led6}->{pallet} = $colors{cyan}; $self->{led6}->{scrolldirection} = "right"; LedPanelDisplay->Init($self->{led6}); $self->{led7} = LedPanelDisplay->new(width => 216, height =>7, ledsize => 10, id => "led7"); $self->{led7}->{message} = "LINE 7 {|}~ "; $self->{led7}->{pallet} = $colors{gray}; $self->{led7}->{scrolldirection} = "left"; LedPanelDisplay->Init($self->{led7}); EVT_PAINT($self, \&onPaint); EVT_TIMER($self, -1, \&onTimer); my $timer = Wx::Timer->new($self); $timer->Start(1000); return $self; } 1; sub onTimer { my($self, $event) = @_; my @displays = qw(led1 led2 led3 led4 led5 led6 led7); foreach my $display (@displays) { if($self->{$display}->{scrolldirection} eq "none") {next;} if($self->{$display}->{scrolldirection} eq "left") { LedPanelMatrix->ShiftLeft($self->{$display}->{dispmat});} if($self->{$display}->{scrolldirection} eq "right") { LedPanelMatrix->ShiftRight($self->{$display}->{dispmat});} if($self->{$display}->{scrolldirection} eq "up") { LedPanelMatrix->ShiftUp($self->{$display}->{dispmat});} if($self->{$display}->{scrolldirection} eq "down") { LedPanelMatrix->ShiftDown($self->{$display}->{dispmat});} } $self->Refresh(0); } sub onPaint { my($self, $event) = @_; # # Draw the Seven Led Displays # LedPanelDisplay->Draw($self->{LP1}, $self->{led1}); LedPanelDisplay->Draw($self->{LP2}, $self->{led2}); LedPanelDisplay->Draw($self->{LP3}, $self->{led3}); LedPanelDisplay->Draw($self->{LP4}, $self->{led4}); LedPanelDisplay->Draw($self->{LP5}, $self->{led5}); LedPanelDisplay->Draw($self->{LP6}, $self->{led6}); LedPanelDisplay->Draw($self->{LP7}, $self->{led7}); } #! /home/pete/CitrusPerl/perl/bin/perl # Create a LedPanel Display Object # # Based on a wxWidgets C++ application by Christian Gr�fe (info@mcs-soft.de) # Reimplemented in wxPerl by James M. Lynes, Jr # Last Modified: March 14, 2013 # package LedPanelDisplay; use strict; use warnings; use Wx qw(:everything); use LedPanelMatrix; use LedPanelCtbl; use LedPanelColourTbl; use Data::Dumper; sub new { my $class = shift; my $self = { width => 0, height => 0, ledsize => 4, spacing => 1, message => "", scrolldirection => "none", invert => 0, showinactives => 1, id => [], pallet => 0, bgcolor => wxBLACK, @_, }; bless($self, $class); return $self; } 1; # # Set up the Led On, Off, & None bitmaps for this display # sub LedPanelDisplay::Init { my($class, $self) = @_; $self->{memdcLedOn} = LedPanelDisplay->LedOnMemDc($self); $self->{memdcLedOff} = LedPanelDisplay->LedOffMemDc($self); $self->{memdcLedNone} = LedPanelDisplay->LedNoneMemDc($self); $self->{dispmat} = LedPanelDisplay->BuildMatrix($self); if(!$self->{invert}) { $self->{memdcLed1} = $self->{memdcLedOn}; $self->{memdcLed0} = $self->{memdcLedOff}; } if($self->{invert}) { $self->{memdcLed1} = $self->{memdcLedOff}; $self->{memdcLed0} = $self->{memdcLedOn}; } if(!$self->{showinactives}) { $self->{memdcLed0} = $self->{memdcLedNone}; } } # # Draw each LED by copying the appropriate(On, Off, None) bitmap into the DC # sub LedPanelDisplay::Draw { my($class, $panel, $self) = @_; my $disp = Wx::PaintDC->new($panel); my $sz = $self->{ledsize}; my $bmw = $self->{dispmat}->{columns}; my $bmh = $self->{height}; my $w = 0; my $h = 0; for my $r (0..$bmh-1) { for my $c (0..$bmw-1) { if($self->{dispmat}->{matrix}[$r][$c] == 1) { $disp->Blit($w,$h,$sz,$sz,$self->{memdcLed1},0,0); $w = $w + $sz; } else { $disp->Blit($w,$h,$sz,$sz,$self->{memdcLed0},0,0); $w = $w + $sz; } } $h = $h + $sz; $w = 0; } return; } # # Create the LedOn bitmap/memory DC # sub LedPanelDisplay::LedOnMemDc { my($class, $self) = @_; my $sz = $self->{ledsize}; my $LedOn = Wx::Bitmap->new($sz,$sz); my $memdcLedOn = Wx::MemoryDC->new(); my $brush = Wx::Brush->new($self->{bgcolor}, wxSOLID); $memdcLedOn->SelectObject($LedOn); $memdcLedOn->SetBackground($brush); $memdcLedOn->Clear(); my $pallet = LedPanelColourTbl->new(); my $pen = Wx::Pen->new(($pallet->{dark}[$self->{pallet}]), 1, wxSOLID); $brush = Wx::Brush->new(($pallet->{base}[$self->{pallet}]), wxSOLID); $memdcLedOn->SetPen($pen); $memdcLedOn->SetBrush($brush); $memdcLedOn->DrawEllipse(0,0,$sz,$sz); $pen = Wx::Pen->new(($pallet->{light}[$self->{pallet}]), 1, wxSOLID); $memdcLedOn->SetPen($pen); $memdcLedOn->DrawEllipticArc(0,0,$sz,$sz,75,195); return $memdcLedOn; } # # Create the LedOff bitmap/memory DC # sub LedPanelDisplay::LedOffMemDc { my($class, $self) = @_; my $sz = $self->{ledsize}; my $LedOff = Wx::Bitmap->new($sz,$sz); my $memdcLedOff = Wx::MemoryDC->new(); my $brush = Wx::Brush->new($self->{bgcolor}, wxSOLID); $memdcLedOff->SelectObject($LedOff); $memdcLedOff->SetBackground($brush); $memdcLedOff->Clear(); my $pallet = LedPanelColourTbl->new(); my $pen = Wx::Pen->new(($pallet->{dark}[$self->{pallet}]), 1, wxSOLID); $brush = Wx::Brush->new(($pallet->{verydark}[$self->{pallet}]), wxSOLID); $memdcLedOff->SetPen($pen); $memdcLedOff->SetBrush($brush); $memdcLedOff->DrawEllipse(0,0,$sz,$sz); return $memdcLedOff; } # # Create the LedNone bitmap/memory DC # sub LedPanelDisplay::LedNoneMemDc { my($class, $self) = @_; my $sz = $self->{ledsize}; my $LedNone = Wx::Bitmap->new($sz,$sz); my $memdcLedNone = Wx::MemoryDC->new(); my $brush = Wx::Brush->new($self->{bgcolor}, wxSOLID); $memdcLedNone->SelectObject($LedNone); $memdcLedNone->SetBackground($brush); $memdcLedNone->Clear(); return $memdcLedNone; } # # Create the display bitmap from the message text and spacing paramrters # sub LedPanelDisplay::BuildMatrix { my($class, $self) = @_; my $ctbl = LedPanelCtbl->new(); my $spacemat = LedPanelMatrix->new(width => 1, height =>7); LedPanelMatrix->fill($spacemat, [[0],[0],[0],[0],[0],[0],[0]]); my $charmat = LedPanelMatrix->new(width => 5, height =>7); my $dispmat = LedPanelMatrix->new(width => 80, height => 7); my $tmpmat = LedPanelMatrix->new(width => 80, height =>7); my @text = (split //, $self->{message}); for my $char (@text) { LedPanelCtbl->expand($ctbl, $char, $charmat); LedPanelMatrix->append($dispmat, $charmat, $tmpmat); for my $spaces (1..$self->{spacing}) { LedPanelMatrix->append($dispmat, $spacemat, $tmpmat); } } return $dispmat; } #! /home/pete/CitrusPerl/perl/bin/perl # Create a matrix to hold a bitmap for display definition # The bitmap will be two dimensional - rows x columns # 7 rows, columns will be 5x number of characters in the message # plus the spacing columns. # # Based on a wxWidgets C++ application by Christian Gr�fe (info@mcs-soft.de) # Reimplemented in wxPerl by James M. Lynes, Jr # Last Modified: March 14, 2013 package LedPanelMatrix; use strict; use warnings; use Wx qw(:everything); use Data::Dumper; sub new { my $class = shift; my $self = { width => 0, height => 0, columns => 0, matrix => [], @_, }; bless($self, $class); return $self; } 1; # # Fill a matrix with a source value(s) # sub LedPanelMatrix::fill { my($class, $self, @source) = @_; for my $i (0..($self->{width}-1)) { for my $j (0..($self->{height}-1)) { push ($self->{matrix}, $source[$i][$j]); } } $self->{columns} = $self->{width}; return; } # # Append a source matrix to a destination matrix - add a character or space matrix to the display matrix # sub LedPanelMatrix::append { my($class, $destobj, $sourceobj, $tmpobj) = @_; my $dw = $destobj->{width}; my $dh = $destobj->{height}; my $dc = $destobj->{columns}; my $sw = $sourceobj->{width}; my $sh = $sourceobj->{height}; for my $r (0..$dh-1) { if($dc > 0) { for my $c (0..$dc-1) { $tmpobj->{matrix}[$r][$c] = $destobj->{matrix}[$r][$c]; } } my $ctr = $dc; for my $c (0..$sw-1) { $tmpobj->{matrix}[$r][$ctr] = $sourceobj->{matrix}[$r][$c]; $ctr++; } } $destobj->{matrix} = $tmpobj->{matrix}; $destobj->{columns} = $destobj->{columns} + $sourceobj->{width}; } # # Shift the matrix left by one column, first column wraps to last column # sub LedPanelMatrix::ShiftLeft { my($class, $mobj) = @_; my $mw = $mobj->{columns}; my $mh = $mobj->{height}; my $tmpobj = LedPanelMatrix->new(width => 1, height => $mh); for my $r (0..$mh-1) { $tmpobj->{matrix}[$r][0] = $mobj->{matrix}[$r][0]; } for my $r (0..$mh-1) { for my $c (0..$mw-2) { $mobj->{matrix}[$r][$c] = $mobj->{matrix}[$r][$c+1]; } $mobj->{matrix}[$r][$mw-1] = $tmpobj->{matrix}[$r][0]; } } # # Shift the matrix right by one column, last column wraps to first column # sub LedPanelMatrix::ShiftRight { my($class, $mobj) = @_; my $mw = $mobj->{columns}; my $mh = $mobj->{height}; my $tmpobj = LedPanelMatrix->new(width => 1, height => $mh); for my $r (0..$mh-1) { $tmpobj->{matrix}[$r][0] = $mobj->{matrix}[$r][$mw-1]; } for my $r (0..$mh-1) { for my $c (0..$mw-2) { $mobj->{matrix}[$r][$mw-1-$c] = $mobj->{matrix}[$r][$mw-2-$c]; } $mobj->{matrix}[$r][0] = $tmpobj->{matrix}[$r][0]; } } # # Shift the matrix up by one row, top row wraps to bottom row # sub LedPanelMatrix::ShiftUp { my($class, $mobj) = @_; my $mw = $mobj->{columns}; my $mh = $mobj->{height}; my $tmpobj = LedPanelMatrix->new(width => $mw, height => 1); for my $c (0..$mw-1) { $tmpobj->{matrix}[0][$c] = $mobj->{matrix}[0][$c]; } for my $c (0..$mw-1) { for my $r (0..$mh-2) { $mobj->{matrix}[$r][$c] = $mobj->{matrix}[$r+1][$c]; } $mobj->{matrix}[$mh-1][$c] = $tmpobj->{matrix}[0][$c]; } } # # Shift the matrix down by one row, bottom row wraps to top row # sub LedPanelMatrix::ShiftDown { my($class, $mobj) = @_; my $mw = $mobj->{columns}; my $mh = $mobj->{height}; my $tmpobj = LedPanelMatrix->new(width => $mw, height => 1); for my $c (0..$mw-1) { $tmpobj->{matrix}[0][$c] = $mobj->{matrix}[$mh-1][$c]; } for my $c (0..$mw-1) { for my $r (0..$mh-2) { $mobj->{matrix}[$mh-$r-1][$c] = $mobj->{matrix}[$mh-$r-2][$c]; } $mobj->{matrix}[0][$c] = $tmpobj->{matrix}[0][$c]; } } #! /home/pete/CitrusPerl/perl/bin/perl # Create a table to hold the color pallet definitions # One row per pallet # 0 1 2 3 4 5 6 (array index) # Red, Green, Blue, Yellow, Magenta, Cyan, Gray # Each color has 4 shades - base, dark, verydark, & light # # Based on a wxWidgets C++ application by Christian Gr�fe (info@mcs-soft.de) # Reimplemented in wxPerl by James M. Lynes, Jr # Last Modified: March 14, 2013 package LedPanelColourTbl; use strict; use warnings; use Wx qw(:everything); use Data::Dumper; sub new { my $class = shift; my $self = { base => [Wx::Colour->new(255, 0, 0), Wx::Colour->new( 0,255, 0), Wx::Colour->new( 0, 0,255), Wx::Colour->new(255,255, 0), Wx::Colour->new(255, 0,255), Wx::Colour->new( 0,255,255), Wx::Colour->new(128,128,128)], dark => [Wx::Colour->new(128, 0, 0), Wx::Colour->new( 0,128, 0), Wx::Colour->new( 0, 0,128), Wx::Colour->new(128,128, 0), Wx::Colour->new(128, 0,128), Wx::Colour->new( 0,128,128), Wx::Colour->new( 64, 64, 64)], verydark => [Wx::Colour->new( 64, 0, 0), Wx::Colour->new( 0, 64, 0), Wx::Colour->new( 0, 0, 64), Wx::Colour->new( 64 ,64, 0), Wx::Colour->new( 64, 0, 64), Wx::Colour->new( 0 ,64, 64), Wx::Colour->new( 32, 32, 32)], light => [Wx::Colour->new(255,128,128), Wx::Colour->new(128,255,128), Wx::Colour->new(128,128,255), Wx::Colour->new(255,255,128), Wx::Colour->new(255,128,255), Wx::Colour->new(128,255,255), Wx::Colour->new(192,192,192)], }; bless($self, $class); return $self; } 1; #! /home/pete/CitrusPerl/perl/bin/perl # Create a table to hold the character definitions for display definition # One row per character # 5x7 matrix - 35 bits # # Based on a wxWidgets C++ application by Christian Gr�fe (info@mcs-soft.de) # Reimplemented in wxPerl by James M. Lynes, Jr # Last Modified: March 14, 2013 package LedPanelCtbl; use strict; use warnings; use Wx qw(:everything); use Data::Dumper; sub new { my $class = shift; my $self = { 0 => [0x0E, 0x11, 0x13, 0x15, 0x19, 0x11, 0x0E], 1 => [0x04, 0x0C, 0x14, 0x04, 0x04, 0x04, 0x0E], 2 => [0x0E, 0x11, 0x01, 0x02, 0x04, 0x08, 0x1F], 3 => [0x0E, 0x11, 0x01, 0x0E, 0x01, 0x11, 0x0E], 4 => [0x02, 0x06, 0x0A, 0x12, 0x1F, 0x02, 0x02], 5 => [0x1F, 0x10, 0x10, 0x0E, 0x01, 0x01, 0x1E], 6 => [0x06, 0x08, 0x10, 0x1E, 0x11, 0x11, 0x0E], 7 => [0x1F, 0x01, 0x02, 0x04, 0x08, 0x08, 0x08], 8 => [0x0E, 0x11, 0x11, 0x0E, 0x11, 0x11, 0x0E], 9 => [0x0E, 0x11, 0x11, 0x0F, 0x01, 0x01, 0x0E], A => [0x0E, 0x11, 0x11, 0x11, 0x1F, 0x11, 0x11], B => [0x1E, 0x11, 0x11, 0x1E, 0x11, 0x11, 0x1E], C => [0x0E, 0x11, 0x10, 0x10, 0x10, 0x11, 0x0E], D => [0x1C, 0x12, 0x11, 0x11, 0x11, 0x12, 0x1C], E => [0x1F, 0x10, 0x10, 0x1E, 0x10, 0x10, 0x1F], F => [0x1F, 0x10, 0x10, 0x1E, 0x10, 0x10, 0x10], G => [0x0E, 0x11, 0x10, 0x17, 0x11, 0x11, 0x0E], H => [0x11, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x11], I => [0x0E, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0E], J => [0x07, 0x02, 0x02, 0x02, 0x02, 0x12, 0x0C], K => [0x11, 0x12, 0x14, 0x18, 0x14, 0x12, 0x11], L => [0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F], M => [0x11, 0x1B, 0x15, 0x15, 0x11, 0x11, 0x11], N => [0x11, 0x19, 0x15, 0x13, 0x11, 0x11, 0x11], O => [0x0E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E], P => [0x1E, 0x11, 0x11, 0x1E, 0x10, 0x10, 0x10], Q => [0x0E, 0x11, 0x11, 0x11, 0x15, 0x0E, 0x01], R => [0x1E, 0x11, 0x11, 0x1E, 0x14, 0x12, 0x11], S => [0x0E, 0x11, 0x10, 0x0E, 0x01, 0x11, 0x0E], T => [0x1F, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04], U => [0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E], V => [0x11, 0x11, 0x11, 0x11, 0x11, 0x0A, 0x04], W => [0x11, 0x11, 0x11, 0x15, 0x15, 0x1B, 0x11], X => [0x11, 0x11, 0x0A, 0x04, 0x0A, 0x11, 0x11], Y => [0x11, 0x11, 0x0A, 0x04, 0x04, 0x04, 0x04], Z => [0x1F, 0x01, 0x02, 0x04, 0x08, 0x10, 0x1F], a => [0x00, 0x00, 0x0E, 0x01, 0x0F, 0x11, 0x0F], b => [0x10, 0x10, 0x1E, 0x11, 0x11, 0x11, 0x1E], c => [0x00, 0x00, 0x0F, 0x10, 0x10, 0x10, 0x0F], d => [0x01, 0x01, 0x0F, 0x11, 0x11, 0x11, 0x0F], e => [0x00, 0x00, 0x0E, 0x11, 0x1F, 0x10, 0x0E], f => [0x06, 0x08, 0x08, 0x1C, 0x08, 0x08, 0x08], g => [0x00, 0x0E, 0x11, 0x11, 0x0F, 0x01, 0x0E], h => [0x10, 0x10, 0x16, 0x19, 0x11, 0x11, 0x11], i => [0x04, 0x00, 0x0C, 0x04, 0x04, 0x04, 0x0E], j => [0x02, 0x00, 0x06, 0x02, 0x02, 0x0A, 0x04], k => [0x10, 0x10, 0x12, 0x14, 0x18, 0x14, 0x12], l => [0x0C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0E], m => [0x00, 0x00, 0x1A, 0x15, 0x15, 0x15, 0x15], n => [0x00, 0x00, 0x16, 0x19, 0x11, 0x11, 0x11], o => [0x00, 0x00, 0x0E, 0x11, 0x11, 0x11, 0x0E], p => [0x00, 0x00, 0x1C, 0x12, 0x12, 0x1C, 0x10], q => [0x00, 0x00, 0x0E, 0x12, 0x12, 0x0E, 0x02], r => [0x00, 0x00, 0x16, 0x18, 0x10, 0x10, 0x10], s => [0x00, 0x00, 0x0E, 0x10, 0x0E, 0x01, 0x0E], t => [0x08, 0x08, 0x1C, 0x08, 0x08, 0x0A, 0x04], u => [0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x0E], v => [0x00, 0x00, 0x11, 0x11, 0x11, 0x0A, 0x04], w => [0x00, 0x00, 0x11, 0x11, 0x15, 0x15, 0x0A], x => [0x00, 0x00, 0x11, 0x0A, 0x04, 0x0A, 0x11], y => [0x00, 0x00, 0x11, 0x0A, 0x04, 0x04, 0x04], z => [0x00, 0x00, 0x1F, 0x02, 0x04, 0x08, 0x1F], '!' => [0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x04], '"' => [0x0A, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00], '#' => [0x0A, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x0A], '$' => [0x04, 0x0E, 0x10, 0x0E, 0x01, 0x0E, 0x04], '%' => [0x01, 0x09, 0x02, 0x04, 0x08, 0x12, 0x10], '&' => [0x0C, 0x12, 0x12, 0x0C, 0x13, 0x12, 0x0D], '(' => [0x02, 0x04, 0x08, 0x08, 0x08, 0x04, 0x02], ')' => [0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08], '*' => [0x00, 0x04, 0x15, 0x0E, 0x15, 0x04, 0x00], '+' => [0x00, 0x04, 0x04, 0x1F, 0x04, 0x04, 0x00], ',' => [0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10], '-' => [0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00], '.' => [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10], '/' => [0x01, 0x01, 0x02, 0x04, 0x08, 0x10, 0x10], ':' => [0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00], ';' => [0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x10], '<' => [0x00, 0x02, 0x04, 0x08, 0x04, 0x02, 0x00], '=' => [0x00, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x00], '>' => [0x00, 0x08, 0x04, 0x02, 0x04, 0x08, 0x00], '?' => [0x0E, 0x11, 0x01, 0x02, 0x04, 0x00, 0x04], '@' => [0x0E, 0x11, 0x17, 0x15, 0x17, 0x10, 0x0E], '[' => [0x0E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0E], ']' => [0x0E, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0E], '^' => [0x04, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00], '_' => [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F], '`' => [0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00], '{' => [0x02, 0x04, 0x04, 0x08, 0x04, 0x04, 0x02], '|' => [0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04], '}' => [0x08, 0x04, 0x04, 0x02, 0x04, 0x04, 0x08], '~' => [0x00, 0x00, 0x0A, 0x14, 0x00, 0x00, 0x00], ' ' => [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], }; bless($self, $class); return $self; } 1; # # Expand a row above into a 5 x 7 matrix - makes the Ctbl definition more compact # sub LedPanelCtbl::expand { my($class, $self, $char, $destobj) = @_; my $dw = $destobj->{width}; my $dh = $destobj->{height}; my $dc = $destobj->{columns}; for my $r (0..$dh-1) { my $c = 0; for my $b (0..4) { $destobj->{matrix}[$r][$c] = ($self->{$char}[$r] >> (4-$b) & 0x01); $c++; } } $destobj->{columns} = 5; }