Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

toddburch

macrumors 6502a
Original poster
Dec 4, 2006
748
0
Katy, Texas
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
 
pancakebunnylf3.jpg



Could you post a pic of what you are talking about? Is it like ASCII art?
 
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

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
 
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
 
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
 
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

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.
 
I'm getting question marks for all the characters, in a nice square!. Any ideas?

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
 
I've defined several of the cursor positioning, and foreground and background attributes, but I can't get the box-border characters to display.

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).
 
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...

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;
}

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...

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 :)
 
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
 
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
 
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;
}

Interesting technique - casting a return value to void. I didn't know you could do that, but it makes sense!

Thanks! Todd
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.