Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

80x25 ASCII text art in terminal

by harangzsolt33 (Deacon)
on Jun 17, 2023 at 23:52 UTC ( [id://11152937]=perlquestion: print w/replies, xml ) Need Help??

harangzsolt33 has asked for the wisdom of the Perl Monks concerning the following question:

I have tried to print a simple ASCII art in Perl. The problem I am running into is that if my terminal window is 80x25 characters, then every time I print the last character in the lower right-hand corner, the little cursor wants to jump over to the next line which causes the entire screen to scroll up by one line. Then the first line disappears and the bottom line becomes blank. So, I can never print the last character of an ASCII art picture. Is there a way to do this somehow without using graphics? I wanted to print a full-screen ASCII art that covers the entire 80x25 screen without jumping over to the next line. Once the last character is printed, I want the program to sleep for a second before clearing the screen and then printing another full-screen text art. So, the result would be like an animation.

80 x 25 = 2000

If I print 1999 characters, it doesn't scroll. But the picture doesn't look good when the bottom right-hand corner character is always missing. :(

Replies are listed 'Best First'.
Re: 80x25 ASCII text art in terminal
by tybalt89 (Monsignor) on Jun 18, 2023 at 00:39 UTC

    I've seen this before, it depends on the terminal.

    I can run this on my system (ArchLinux) in an xterm, and it works properly.

    #!/usr/bin/perl use strict; use warnings; $SIG{__WARN__} = sub { die @_ }; $| = 1; print "x" x 2000; sleep 5;

    It fills an 80x25 screen with 'x' and does not go to the next line until after it exits. It is in fact why I use xterms, because others I've tried have the problem that was complained about.

      Hmm... so it seems that this is something that depends on the terminal and the system. Well, thank you.

        Yes, there are many, MANY different terminals and terminal emulators out there. Don't forget, the modern'ish terminal you see on your modern flat panel screen is basically an emulator of an old school serial (or parallel or network or $other) terminal.

        Some of these has local computing options, many were of the type "connect to the mainframe in the basement", basically glorified teletype machines that used a screen instead of paper. These all started as proprietary developments of the different mainframe manufacturers (IBM, HP, Cray, ...), with cross-compatibility coming later as an afterthought.

        But even compatible systems often had their hardware (later software) quirks. And it's these quirks that are still in existance on modern terminal emulators. Because they need to be compatible of the old software.

        Often, your best bet is to use a terminal library like ncurses or curses to help you position text on screen. These libraries know a lot of the tricks of the trade and can handle all the required workarounds for you.

        PerlMonks XP is useless? Not anymore: XPD - Do more with your PerlMonks XP
Re: 80x25 ASCII text art in terminal
by cavac (Prior) on Jun 21, 2023 at 13:22 UTC

    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.

    PerlMonks XP is useless? Not anymore: XPD - Do more with your PerlMonks XP

      There's already a perl interface to aalib, so that probably takes care of images rendered as ascii (as opposed to more line-oriented ascii art that humans would produce).

      Had you seen TTY Quake before? Sadly it doesn't seem that anyone has uploaded a Youtube video of it, but there is TTY World of Warcraft

      I have a bzcat movie of TTYQuake somewhere lost in my old backups of harddrives I think. I should hunt that down...

      Of course, printing ASCII art monochrome so boooring. Thankfully, someone invented colors in the 1990's.

      Nope.

      ANSI.SYS was included in MS-DOS since at least 3.3, i.e. 1988.

      The HP 2627A terminal had 8 colors on a CRT, it was build in 1982. (But it looks like it does not understand ANSI standard color codes.)

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11152937]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2025-06-18 02:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.