Character graphics with C/C++ in Terminal. How to?

Discussion in 'Mac Programming' started by toddburch, May 14, 2007.

  1. macrumors 6502a

    Joined:
    Dec 4, 2006
    Location:
    Katy, Texas
    #1
    I searched and couldn't find anything.

    Does anyone have a reference to point me to for learning how to do character based graphics in Terminal? I'm referring to using the "box" characters with horizontal, vertical, and all 4 corners, either in single or double line.

    Or, is this just a PC thing?

    I tried printing all 256 character to Terminal from a small C app, and I either got question marks or octal codes. I tried different character sets from the Terminal Preferences also. No joy.

    Also, I would need to set a cursor postition, change text character color, and also define some fields as input, allow use of the tab keys, etc...

    Todd
     
  2. macrumors 68020

    Joined:
    Mar 21, 2006
    Location:
    Hoosiertown
    #2
    [​IMG]


    Could you post a pic of what you are talking about? Is it like ASCII art?
     
  3. macrumors 6502a

    Joined:
    Sep 3, 2005
    Location:
    Cramlington, UK
    #3
    You can use ANSI escape sequences to do most of the above. Have a look at http://en.wikipedia.org/wiki/ANSI_escape_code

    As for graphics characters… you can use the Character Palette to insert the characters straight into your source code. So long as your source file is using UTF-8 or UTF-16 encoding I think this will work… at least is does for me though I must admit I haven't got very satisfactory results. For example I haven't been able to get the characters that make the box up to actually join up. Must have something to do with the terminal font settings or something like that. If you get it to work I'd be really intereted to know how you did it!

    b e n
     
  4. thread starter macrumors 6502a

    Joined:
    Dec 4, 2006
    Location:
    Katy, Texas
    #4
    OK good. I'm making progress with the information on wiki page. Thanks. Should know later this evening how well it works.

    Thanks Ben.
    Todd
     
  5. thread starter macrumors 6502a

    Joined:
    Dec 4, 2006
    Location:
    Katy, Texas
    #5
    I've defined several of the cursor positioning, and foreground and background attributes, but I can't get the box-border characters to display.

    I'm using these characters:
    • (unsigned char) 201 for the top left of the box.
    • (unsigned char) 187 for the top right.
    • (unsigned char) 200 for the bottom left
    • (unsigned char) 188 for the bottom right.
    • (unsigned char) 205 for the horizontals
    • (unsigned char) 186 for the verticals.
    The box-border characters I'm referring to are here: http://www.pcmag.com/encyclopedia_term/0,2542,t=ASCII+chart&i=38015,00.asp

    I'm using these like this: (to draw a square)
    Code:
    setrowcol(1,1) ; 
    cout << (unsigned char) 201 ;
    setrowcol(1,2) ; 
    cout << (unsigned char) 205 ;
    setrowcol(1,3) ; 
    cout << (unsigned char) 187 ;
    setrowcol(2,1) ; 
    cout << (unsigned char) 186 ; 
    setrowcol(2,3) ; 
    cout << (unsigned char) 186 ; 
    setrowcol(3,1) ; 
    cout << (unsigned char) 200 ;
    setrowcol(3,2) ; 
    cout << (unsigned char) 205 ; 
    setrowcol(3,3) ; 
    cout << (unsigned char) 188 ;  
    
    I'm getting question marks for all the characters, in a nice square!. Any ideas?

    Here's an example function I've written to set the cursor row & column:

    Code:
    void setrowcol(int row, int col) { cout << esc << row << ';' << col << 'H'  ; return ; }
    esc is defined as a char esc[3] of with values 0x1b, '[' & NULL.

    Todd
     
  6. macrumors 6502a

    csubear

    Joined:
    Aug 22, 2003
    #6
    I'd mess with your emulation settings in terminal's window settings. Also declaring your $TERM variable differently in terminal's preferences may help too.
     
  7. macrumors 6502a

    Joined:
    Sep 3, 2005
    Location:
    Cramlington, UK
    #7
    I think it's because the terminal is set to use UTF-8. Check the window settings for your terminal. In UTF-8 the characters you are trying to print are probably illegal. The easiest way is to paste those characters straight into your code. That way they will be encoded correctly. In UTF-8 any character with a value greater than 127 is encoded as a sequence of bytes. Like I said I use the Character Palette application to do this. For example in the line below I've pasted 3 Chess characters straight into the string. They will probably come up as question marks in the browser unfortunately but nevertheless in my source file and in the terminal window when the program runs I get 3 chess characters after the Hello World! text.

    Code:
    std::cout << "Hello, World! ???\n"; 
    
    The other option is set the character encoding for your terminal window to Western ANSI… that may then work with your existing code.

    b e n
     
  8. macrumors G3

    iMeowbot

    Joined:
    Aug 30, 2003
    #8
    That's because those character codes are specific to the IBM PC and clones. See http://unicode.org/charts/PDF/U2500.pdf for standard equivalents.

    You may want to look into ncurses, which comes with OS X and most other POSIX systems. there is a bit of a learning curve, but it will take care of things like drawing boxes without worryng about the character set (for example, in an ASCII environment, it can substitute hyphens, pipes and pluses for the missing pretty lines).
     
  9. macrumors member

    Joined:
    Jan 18, 2006
    Location:
    Finland
    #9
    IMHO curses/ncurses is pretty easy to use and very powerful, too.

    Code:
    #include <curses.h>
    
    // gcc -W -Wall -Werror foo.c -lncurses
    int main(void)
    {
      WINDOW* w;
    
      (void)initscr();
    
      w = newwin(3, 3, 1, 1);  // 3x3 including border
      (void)box(w, 0, 0);      // draw border
      (void)wmove(w, 1, 1);    // top-left is (0,0);  place cursor in middle of 'w'
      (void)wrefresh(w);
    
      (void)getc(stdin);       // press a key to exit
      (void)delwin(w);
      (void)endwin();
      return 0;
    }
    Curses provides the screen-related infrastructure for these tasks; but you will still have some work to do, in order to support field-based input etc. Good luck with your project :)
     
  10. macrumors 68020

    pilotError

    Joined:
    Apr 12, 2006
    Location:
    Long Island
    #10
    you can do a man -k curses in the terminal window and see all the related calls.

    Pretty easy stuff, good for terminal admin software.

    I guess Rokem isn't old enough to remember terminal graphics LOL ... oh wait, that sad (for me) :( :D
     
  11. thread starter macrumors 6502a

    Joined:
    Dec 4, 2006
    Location:
    Katy, Texas
    #11
    Looks like ncurses will foot the bill. man ncurses tells me everything I need to know for now. Lots of info - lots to absorb. I've decided to put this on the back burner for now. It's certainly doable, but the initial learning curve is more involved that I anticipated.

    Again, you all are champs!

    Thanks, Todd
     
  12. thread starter macrumors 6502a

    Joined:
    Dec 4, 2006
    Location:
    Katy, Texas
    #12
    Interesting technique - casting a return value to void. I didn't know you could do that, but it makes sense!

    Thanks! Todd
     
  13. thread starter macrumors 6502a

    Joined:
    Dec 4, 2006
    Location:
    Katy, Texas
    #13
    Ok, now I have question. How to set up XCode to point to the proper library?

    Thanks, Todd
     

Share This Page