Thread: How do I use a text terminal as a bitmap?

  1. #1
    Registered User
    Join Date
    Feb 2004
    Posts
    42

    How do I use a text terminal as a bitmap?

    1 pixel being one chat.

    I've googled a bit around but all results mentioned curses like libraries, that, if I understand it correctly, are more like a widget library than a canvas so to speak.
    I would like to work at a lower level, but I don't have a good grasp of how a terminal really works.

    Say I want to draw a cross of chars 'A' dividing the screen in half. Could anybody show me a simple snipet that would get me started?

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Do you mean 1 pixel being one char?

    Ncurses is a header file to allow easy handling of text console screens (similar to the conio.h header file from DOS days).

    Standard C has nothing to support output devices, directly, preferring to stay "above" that level, since many devices don't use or have, output devices.

    If you want to make a cross of A's to divide the screen:

    midx= 40, midy=15 (or whatever half your vertical console screen may be), and then

    Code:
    for(row=1;row<maxy;row++) {
       for(col=1;col<80;col++) {
           if row == midy, print the char 
           else if col ==midx print the char
    
           etc.
       }
    }
    The above should get you well started on thinking this through, but it's not ready to run code.

  3. #3
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by PedroTuga View Post
    curses like libraries, that, if I understand it correctly, are more like a widget library than a canvas so to speak.
    They do include the "canvas" level, too. For example, save the following as example.c,
    Code:
    #include <curses.h>
    #include <string.h>
    
    int main(void)
    {
        static const char msg[] = "Press Q to Quit";
        int               c;
    
        /* Start curses. Also sets LINES and COLS. */
        initscr();
    
        /* Pass every character immediately, not buffered. */
        cbreak();
    
        do {
            /* Clear the screen. */
            erase();
    
            /* Print "X" at the center of the screen, */
            mvaddch(LINES/2, COLS/2, 'X');
    
            /* and msg centered at the bottom. */
            mvaddstr(LINES-1, (COLS-strlen(msg))/2, msg);
    
            /* Move the cursor to the center of the screen too. */
            move(LINES/2, COLS/2);
    
            /* Refresh the screen. */
            refresh();
    
            /* Wait for a keypress. */
            c = getch();
    
        } while (c != 'Q' && c != 'q');
    
        /* Done. Return the terminal back to its normal state. */
        endwin();
    
        return 0;
    }
    then compile and run it using e.g.
    Code:
    cc example.c -lcurses -o example
    ./example
    It is pretty much the lowest level you should bother.

    If you resize the terminal window -- mine are practically never exactly 80 columns wide, nowadays --, it is seen as a keypress by the above program. Since it is not Q, it will redraw the screen. However, that screen update "keypress" also updates LINES and COLS, which means that the next iteration of the loop will redraw everything correctly, as per the resized terminal window. It's quite nifty, and pretty much exactly what I want from such a "terminal canvas".

    As a programmer, all you need to remember is that COLS is not always 80, and LINES is not always 25 or 43 or 50, and both may change at any point if the user resizes the terminal window.

    In Windows, you can use pdcurses, but I have no idea about the installation or compilation details since I don't use Windows at all. Maybe someone else can point out those details?

  4. #4
    Registered User
    Join Date
    Feb 2004
    Posts
    42
    Thank you Nominal Animal. That is exactly the info I was looking for. being aware of such ncurses capabilities, I narrowed down my googling and found that this how-to on ncurses actually covers such uses of a text terminal rather well. I was being deceived by all the references to ncurses widgets. For some reason, all the documentation on ncurses out there focus too much on windows and widgets.

    For now I'll stick with ncurses, although some time in the future I would actually like to know how terminals work at a lower level. What bugs me with good abstractions (such as ncurses) is that one doesn't get an accurate idea of how much processing power is required to perform a simple task.

  5. #5
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Also check out pdcurses. It is not as feature-rich as ncurses, but the basic terminal access functions are all there. And it compiles/works on Windows as well as Linux.

    In the end, these libraries will eventually call the functions of the host-os. In the case of Windows, this means calling the terminal-handling functions provided by the WIN32API. If its DOS, it means writing the appropriate attribute and character codes to address-range reserved for the text-terminal, etc. Abstraction layers like curses serve to makes it cross-platform compatible because the function calls like mvaddch should do the same thing no matter what system you're on.

  6. #6
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Just about everything -- except Windows, of course -- uses some subset of ANSI escape codes. Many support POSIX.1-2001 termios interface for the terminal settings. In Linux, you'll probably also use at least one tty ioctl (TIOCGWINSZ, to get the new terminal size when a SIGWINCH signal is caught).

    The kernel side support in Linux at least is very lightweight. Almost all the work is really done in your terminal application (or console driver, if you are using e.g. a framebuffer console). If you look at the ANSI escape codes, they're not difficult to support at all. Same for DOS; the libraries just manipulate the display buffer that consists of alternating character and attribute bytes, or rely on ANSI escape codes too, via ANSI.SYS. I suspect even Windows does not do anything overly complicated.

    Overall, the curses interface seems a pretty good abstraction for this, in my opinion. It should not really be a surprise, considering it is decades old already, but still actively developed. ncurses, for example, started as pcurses in 1983 or so. First ncurses (version 1.8.1) was released in 1993.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 0
    Last Post: 03-16-2012, 09:59 AM
  2. Replies: 7
    Last Post: 08-28-2011, 09:01 PM
  3. Replies: 2
    Last Post: 02-11-2011, 04:45 AM
  4. Console, Terminal and Terminal Emulator
    By lehe in forum C Programming
    Replies: 4
    Last Post: 02-15-2009, 09:59 PM
  5. bitmap covers text
    By vn1 in forum Windows Programming
    Replies: 5
    Last Post: 01-08-2003, 02:37 AM

Tags for this Thread