I've mentioned using the Curses library in another reply. With a bit of reading docs and playing around (and, i admit, asking ChatGPT for some extra help), i have come up with this:
#!/usr/bin/env perl
use strict;
use warnings;
use Curses;
my $CENTERIMAGE = 0;
# ASCII art to display
my $art = <<'ASCII_ART';
_______
/ \
| |
| |
\_______/
ASCII_ART
# Initialize Curses
initscr(); # Initialize screen / Start curses mode
noecho(); # Don't echo (display) characters typed by the user
cbreak(); # Line buffering disabled, Pass on
keypad(1); # It enables the reading of function keys like F1, F2, ar
+row keys etc.
curs_set(0); # Hide the active cursor
# Get terminal dimensions
my $rows;
my $cols;
getmaxyx(stdscr(), $rows, $cols);
# Calculate the center position for displaying the ASCII art
my @parts = split/\n/, $art;
my $linecount = scalar @parts;
my $rowcount = 0;
foreach my $part (@parts) {
if(length($part) > $rowcount) {
$rowcount = length($part);
}
}
my ($xoffs, $yoffs);
if($CENTERIMAGE) {
# Center
$xoffs = int(($cols - $rowcount) / 2);
$yoffs = int(($rows - $linecount) / 2);
} else {
# Lower right
$xoffs = int(($cols - $rowcount));
$yoffs = int(($rows - $linecount));
}
clear(); # Clear the screen
# Display the ASCII art
for(my $i = 0; $i < $linecount; $i++) {
move($yoffs + $i, $xoffs);
addstr($parts[$i]);
}
refresh(); # Refresh the screen (e.g. actually put what we have drawn
+into the terminal)
getch(); # Wait for a keypress
endwin(); # Exit curses mode
At least the terminals i had quick access too (xfce4-terminal, xterm, bash in screen in xterm, the basic linux shell that starts before loading X11), this seems to work quite well.
If you need something a bit more sophisticated that just putting characters on the screen, Curses::UI comes with all kinds of input fields, textmode-windows, mouse support etc...
Of course, printing ASCII art monochrome so boooring. Thankfully, someone invented colors in the 1990's. Here's the color version:
#!/usr/bin/env perl
use strict;
use warnings;
use Curses;
use Carp;
my $TRANSPARENCY = 0;
# ASCII art to display
my $art = <<'ASCII_ART';
_______
/ \
| |
| |
\_______/
ASCII_ART
# Initialize Curses
initscr(); # Initialize screen / Start curses mode
if(!has_colors()) {
endwin();
croak("Your boring terminal has no color support!");
}
noecho(); # Don't echo (display) characters typed by the user
cbreak(); # Line buffering disabled, Pass on
keypad(1); # It enables the reading of function keys like F1, F2,
+arrow keys etc.
curs_set(0); # Hide the active cursor
start_color(); # Color mode ON!!!!
# Get terminal dimensions
my $rows;
my $cols;
getmaxyx(stdscr(), $rows, $cols);
# Calculate the center position for displaying the ASCII art
my @parts = split/\n/, $art;
my $linecount = scalar @parts;
my $rowcount = 0;
foreach my $part (@parts) {
if(length($part) > $rowcount) {
$rowcount = length($part);
}
}
# Generate the color pairs
my @colors = (COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_
+MAGENTA, COLOR_CYAN, COLOR_WHITE);
my $cnum = 1;
my @colorpairs;
foreach my $color (@colors) {
init_pair($cnum, $color, COLOR_BLACK);
push @colorpairs, COLOR_PAIR($cnum);
$cnum++;
}
clear(); # Clear the screen
# Display the ASCII art
my ($xoffs, $yoffs) = (0,0);
foreach my $colorpair (@colorpairs) {
attron($colorpair);
for(my $i = 0; $i < $linecount; $i++) {
if(!$TRANSPARENCY) {
# No transparency, can print the whole line
addstr($yoffs + $i, $xoffs, $parts[$i]);
} else {
# Only print non-space characters
my @chars = split//, $parts[$i];
my $coloffs = 0;
foreach my $char (@chars) {
if($char ne ' ') {
addstr($yoffs + $i, $xoffs + $coloffs, $char);
}
$coloffs++;
}
}
}
attroff($colorpair);
$xoffs += 2;
$yoffs += 3;
}
refresh(); # Refresh the screen (e.g. actually put what we have drawn
+into the terminal)
getch(); # Wait for a keypress
endwin(); # Exit curses mode
Edit: With a bit of playing around, it should be possible to display low res color images in the text console as well. If you're interested, i would give it a go.