home *** CD-ROM | disk | FTP | other *** search
- /*
-
- gconio.cpp
- 3-30-91
- graphics console class for Borland C++
-
- Copyright 1991
- John W. Small
- All rights reserved
- Use freely but acknowledge authorship and copyright.
- CIS: 73757,2233
-
- PSW / Power SoftWare
- P.O. Box 10072
- McLean, Virginia 22102 8072
- (703) 759-3838
-
- */
-
- #include <gconio.hpp>
- #include <stdio.h>
- #include <stdarg.h>
- #include <dos.h>
-
- GraphicsConsole::GraphicsConsole()
- {
- ColumnLeft = 0;
- InputWriteMode = COPY_PUT;
- InputRewrite = 0;
- InputDone = 0;
- OutputWriteMode = COPY_PUT;
- ClearTextBk = 0;
- TextBkPattern = SOLID_FILL;
- TextBkColor = 0; // 0 = current bkcolor
- CursorChar[0] = '\124'; // 0 = no getch/gets cursor
- CursorChar[1] = '\0';
- CursorOnMsec = 100;
- CursorOffMsec = 100;
- }
-
- void GraphicsConsole::ProportionalBackSpace(int& lastchX,
- int& lastchY, int chX, int chY, char lastch,
- char ch, struct textsettingstype& TS)
- {
- char lastchs[2];
- char chs[2];
- struct textsettingstype tmpTS;
-
- lastchX = chX;
- lastchY = chY;
- lastchs[0] = lastch;
- lastchs[1] = '\0';
- chs[0] = ch;
- chs[1] = '\0';
- gettextsettings(&tmpTS);
- settextstyle(TS.font,TS.direction,TS.charsize);
- if (TS.direction == HORIZ_DIR)
- switch (TS.horiz) {
- case LEFT_TEXT:
- lastchX -= textwidth(lastchs);
- break;
- case CENTER_TEXT:
- lastchX -= (textwidth(chs) >> 1);
- lastchX -= (textwidth(lastchs) >> 1);
- break;
- case RIGHT_TEXT:
- lastchX -= textwidth(chs);
- break;
- }
- else
- switch (TS.vert) {
- case BOTTOM_TEXT:
- lastchY += textwidth(lastchs);
- break;
- case CENTER_TEXT:
- lastchY += (textwidth(chs) >> 1);
- lastchY += (textwidth(lastchs) >> 1);
- break;
- case TOP_TEXT:
- lastchY += textwidth(chs);
- break;
- }
- settextstyle(tmpTS.font,tmpTS.direction,tmpTS.charsize);
- }
-
- void GraphicsConsole::ProportionalSpace(int chX, int chY,
- int& nextchX, int& nextchY, char ch, char nextch,
- struct textsettingstype& TS)
- {
- char chs[2];
- char nextchs[2];
- struct textsettingstype tmpTS;
-
- nextchX = chX;
- nextchY = chY;
- chs[0] = ch;
- chs[1] = '\0';
- nextchs[0] = nextch;
- nextchs[1] = '\0';
- gettextsettings(&tmpTS);
- settextstyle(TS.font,TS.direction,TS.charsize);
- if (TS.direction == HORIZ_DIR)
- switch (TS.horiz) {
- case LEFT_TEXT:
- nextchX += textwidth(chs);
- break;
- case CENTER_TEXT:
- nextchX += (textwidth(chs) >> 1);
- nextchX += (textwidth(nextchs) >> 1);
- break;
- case RIGHT_TEXT:
- nextchX += textwidth(nextchs);
- break;
- }
- else
- switch (TS.vert) {
- case BOTTOM_TEXT:
- nextchY -= textwidth(chs);
- break;
- case CENTER_TEXT:
- nextchY -= (textwidth(chs) >> 1);
- nextchY -= (textwidth(nextchs) >> 1);
- break;
- case TOP_TEXT:
- nextchY -= textwidth(nextchs);
- break;
- }
- settextstyle(tmpTS.font,tmpTS.direction,tmpTS.charsize);
- }
-
- void GraphicsConsole::TextBox(int x, int y, char *s,
- struct textsettingstype& TS,
- int& x1, int& y1, int& x2, int& y2)
- {
- int dx, dy;
- struct textsettingstype tmpTS;
-
- gettextsettings(&tmpTS);
- settextstyle(TS.font,TS.direction,TS.charsize);
- if (TS.direction == HORIZ_DIR) {
- dx = textwidth(s);
- dy = textheight(s);
- // Stroked fonts have long decenders!
- if (TS.font != DEFAULT_FONT)
- y += (dy >> 2);
- }
- else {
- dx = textheight(s);
- dy = textwidth(s);
- // Stroked fonts have long decenders!
- if (TS.font != DEFAULT_FONT) {
- x += (dx >> 2);
- // Correct quirk in outtext[xy]
- if (TS.horiz == CENTER_TEXT)
- if ((dx % 2) != 0)
- x += 2;
- else
- x++;
- }
- }
- settextstyle(tmpTS.font,tmpTS.direction,tmpTS.charsize);
- x1 = x; x2 = x1;
- y1 = y; y2 = y1;
- switch (TS.horiz) {
- case LEFT_TEXT:
- x2 += dx;
- break;
- case CENTER_TEXT:
- x1 -= (dx >> 1);
- x2 += (dx >> 1);
- break;
- case RIGHT_TEXT:
- x1 -= dx;
- break;
- }
- switch (TS.vert) {
- case BOTTOM_TEXT:
- y1 -= dy;
- break;
- case CENTER_TEXT:
- y1 -= (dy >> 1);
- y2 += (dy >> 1);
- break;
- case TOP_TEXT:
- y2 += dy;
- break;
- }
- }
-
- int GraphicsConsole::cprintf(const char *format,...)
- {
- va_list argv;
- int cnt;
- char buf[GC_BUF_SIZE];
-
- va_start(argv,format);
- cnt = vsprintf(buf,format,argv);
- va_end(argv);
- if (cnt)
- cputs(buf);
- return cnt;
- }
-
- int GraphicsConsole::cputs(const char *str)
- {
- int i, j, x, y, x1, y1, x2, y2;
- int bkcolor;
- struct textsettingstype TS;
- struct fillsettingstype FS;
- char buf[GC_BUF_SIZE];
- int ch;
-
- if (!str)
- return 0;
- x = getx(); y = gety();
- gettextsettings(&TS);
- if (ClearTextBk) {
- getfillsettings(&FS);
- bkcolor = TextBkColor? TextBkColor : getbkcolor();
- }
- setwritemode(OutputWriteMode);
- for (i = j = 0; j >= 0; i++) {
- switch (str[i]) {
- case '\r':
- case '\n':
- // fall thru and output buf
- case '\0':
- buf[j] = '\0';
- if (ClearTextBk) {
- setfillstyle(TextBkPattern,bkcolor);
- TextBox(x,y,buf,TS,x1,y1,x2,y2);
- bar(x1,y1,x2,y2);
- setfillstyle(FS.pattern,FS.color);
- }
- outtextxy(x,y,buf);
- if (TS.direction == HORIZ_DIR)
- switch (str[i]) {
- case '\r':
- if (!ColumnLeft &&
- (TS.horiz == LEFT_TEXT))
- x = 0;
- break;
- case '\n':
- y += 1 + textheight(buf);
- break;
- default:
- if (TS.horiz == LEFT_TEXT)
- x += textwidth(buf);
- break;
- }
- else // TS.direction == VERT_DIR
- switch (str[i]) {
- case '\r':
- if (!ColumnLeft &&
- (TS.vert == BOTTOM_TEXT))
- y = getmaxy();
- break;
- case '\n':
- x += 1+textheight(buf);
- break;
- default:
- if (TS.horiz == BOTTOM_TEXT)
- y -= textwidth(buf);
- break;
- }
- moveto(x,y);
- j = (str[i])? 0 : -1;// terminate when ready
- break;
- default:
- if (j < GC_BUF_SIZE - 1)
- ch = buf[j++] = str[i];
- break;
- }
- }
- return ch;
- }
-
- int GraphicsConsole::putch(int c)
- {
- char chs[2];
-
- chs[0] = c; chs[1] = '\0';
- return cputs(chs);
- }
-
- void GraphicsConsole::rubout(int ch)
- {
- int x1, y1, x2, y2, lastchX, lastchY;
- struct textsettingstype TS;
- struct fillsettingstype FS;
- char chs[2];
-
- gettextsettings(&TS);
- // Only works for left justified text!
- if (TS.direction == HORIZ_DIR) {
- if (TS.horiz != LEFT_TEXT)
- return;
- }
- else if (TS.horiz != BOTTOM_TEXT)
- return;
- setwritemode(OutputWriteMode);
- ProportionalBackSpace(lastchX,lastchY,
- getx(),gety(),ch,ch,TS);
- moveto(lastchX,lastchY);
- chs[0] = ch;
- chs[1] = '\0';
- // Only erase XOR_PUT, stroked fonts!
- if ((OutputWriteMode == COPY_PUT) ||
- (TS.font == DEFAULT_FONT)) {
- getfillsettings(&FS);
- if (!TextBkColor)
- setfillstyle(TextBkPattern,getbkcolor());
- else
- setfillstyle(TextBkPattern,TextBkColor);
- TextBox(getx(),gety(),chs,TS,x1,y1,x2,y2);
- bar(x1,y1,x2,y2);
- setfillstyle(FS.pattern,FS.color);
- }
- else {
- outtextxy(getx(),gety(),chs);
- moveto(lastchX,lastchY);
- }
- }
-
- int GraphicsConsole::cscanf(const char *format,...)
- {
- va_list argv;
- int cnt;
- char buf[GC_BUF_SIZE];
-
- buf[0] = GC_BUF_SIZE - 2;
- cgets(buf);
- va_start(argv,format);
- cnt = vsscanf(&buf[2],format,argv);
- va_end(argv);
- return cnt;
- }
-
- char * GraphicsConsole::cgets(char *str)
- {
- int i, imax, x, y, x1, y1, x2, y2;
- int lastchX, lastchY, nextchX, nextchY;
- struct textsettingstype TS;
- struct fillsettingstype FS;
-
- if (!str)
- return str;
- if ((imax = str[0]) < 2)
- return (char *) 0;
- x = getx(); y = gety();
- gettextsettings(&TS);
- setwritemode(InputWriteMode);
- getfillsettings(&FS);
- if (!TextBkColor)
- setfillstyle(TextBkPattern,getbkcolor());
- else
- setfillstyle(TextBkPattern,TextBkColor);
- InputDone = 0;
- str[i = 2] = '\0';
- while (!InputDone) {
- // Cursor only for stroked fonts!
- if (CursorChar[0] && (TS.font != DEFAULT_FONT))
- while (!kbhit() && !InputDone) {
- setwritemode(XOR_PUT);
- if (i > 2)
- ProportionalSpace(getx(),gety(),
- nextchX,nextchY,str[i-1],
- CursorChar[0],TS);
- else {
- nextchX = getx();
- nextchY = gety();
- }
- outtextxy(nextchX,nextchY,CursorChar);
- if (!kbhit())
- delay(CursorOnMsec);
- outtextxy(nextchX,nextchY,CursorChar);
- if (!kbhit())
- delay(CursorOffMsec);
- setwritemode(InputWriteMode);
- }
- // InputDone is also used to interrupt cgets()
- // e.g. by mouse interrupt handler etc.
- while (!kbhit() && !InputDone);
- if (InputDone)
- str[i] = '\13';
- else
- str[i] = getch();
- switch (str[i]) {
- case 13: // Carriage Return
- if (TS.direction == HORIZ_DIR)
- if (!ColumnLeft && (TS.horiz == LEFT_TEXT))
- moveto(0,1+y+textheight("a"));
- else
- moveto(x,1+y+textheight("a"));
- else
- if (!ColumnLeft && (TS.vert == BOTTOM_TEXT))
- moveto(1+x+textheight("a"),getmaxy());
- else
- moveto(1+x+textheight("a"),y);
- str[i] = '\0';
- str[1] = i - 2;
- InputDone = 1;
- break;
- case 8: // Back Space
- if (i > 2) {
- str[i--] = '\0';
- // Only erase XOR_PUT, stroked fonts!
- if ((InputWriteMode == COPY_PUT) ||
- (TS.font == DEFAULT_FONT)) {
- TextBox(getx(),gety(),&str[i],TS,x1,y1,x2,y2);
- bar(x1,y1,x2,y2);
- }
- else
- outtextxy(getx(),gety(),&str[i]);
- if (i > 2) {
- ProportionalBackSpace(lastchX,lastchY,
- getx(),gety(),str[i-1],str[i],TS);
- moveto(lastchX,lastchY);
- }
- str[i] = '\0';
- }
- break;
- default:
- if (i - 2 >= imax) {
- str[i] = '\0';
- break;
- }
- if (i > 2) {
- ProportionalSpace(getx(),gety(),
- nextchX,nextchY,str[i-1],str[i],TS);
- moveto(nextchX,nextchY);
- }
- else {
- nextchX = getx();
- nextchY = gety();
- }
- str[i+1] = '\0';
- if (ClearTextBk) {
- TextBox(nextchX,nextchY,&str[i],TS,x1,y1,x2,y2);
- bar(x1,y1,x2,y2);
- }
- outtextxy(nextchX,nextchY,&str[i]);
- i++;
- break;
- }
- }
- if (InputRewrite && str[1]) {
- setwritemode(COPY_PUT);
- outtextxy(x,y,&str[2]);
- }
- setfillstyle(FS.pattern,FS.color);
- return &str[2];
- }
-
-
- // comment out next line to use gconio in your applications
- #define TEST_GCONIO_CPP
- #ifdef TEST_GCONIO_CPP
-
- #include <stdio.h>
- #include <stdlib.h>
-
- #define MAXS 40
-
- main()
- {
- int gdriver, gmode, gerror;
- int dx, dy, c;
- char s[MAXS];
- GraphicsConsole GC;
-
- gdriver = DETECT;
- initgraph(&gdriver, &gmode, "..\\bgi");
- gerror = graphresult();
- if (gerror != grOk) /* an error occurred */
- {
- printf("Graphics error: %s\n", grapherrormsg(gerror));
- printf("Press any key to halt:");
- getchar();
- exit(1);
- }
-
- dx = getmaxx() / (getmaxcolor()+1);
- clearviewport();
- for (c = 0; c <= getmaxcolor(); c++) {
- setfillstyle(XHATCH_FILL,c);
- bar3d(c*dx,0,(c+1)*dx,getmaxy(),0,0);
- }
- settextjustify(LEFT_TEXT,TOP_TEXT);
- settextstyle(TRIPLEX_FONT,HORIZ_DIR,1);
- GC.cputs("Test getche(): ");
- GC.getche();
- GC.cputs("\r\nTest cscanf(\"Hello %s \",s): ");
- GC.cscanf("Hello %s ",s);
- GC.cprintf("\r\ns: %s",s);
- GC.cputs("\r\n\r\nAnd rubout: ");
- GC.rubout(GC.getche());
-
- GC.ColumnLeft = 1;
- moveto(30,gety());
- GC.cprintf("\r\nHello graphics %s!\r\n\r\n","world");
- GC.cputs("Include gconio.hpp in your application.\r\n");
- GC.cputs("Instantiate the GraphicsConsole class\r\n");
- GC.cputs("to have complete text i/o capabilities\r\n");
- GC.cputs("in all graphics modes.\r\n\r\n");
- GC.cputs("Let's try cgets(). Enter: ");
- s[0] = MAXS-2;
- GC.cgets(s);
- GC.ColumnLeft = 0;
-
-
- setbkcolor(BLUE);
- setcolor(WHITE);
- clearviewport();
- settextstyle(SANS_SERIF_FONT,VERT_DIR,4);
- settextjustify(LEFT_TEXT,BOTTOM_TEXT);
- moveto(0,getmaxy());
- GC.cputs("It even works with\r\n");
- GC.cputs("vertical text.\r\n\r\n");
- GC.cputs("\r\n");
- GC.cputs("And cgets(): ");
- s[0] = MAXS-2;
- GC.cgets(s);
-
- clearviewport();
- settextstyle(GOTHIC_FONT,HORIZ_DIR,4);
- settextjustify(CENTER_TEXT,TOP_TEXT);
- moveto(getmaxx()/2,10);
- GC.cputs("Besure to call GraphicsConsole member\r\n");
- GC.cputs("functions only after calling initgraph()\r\n");
- GC.cputs("and before calling closegraph().");
-
- settextstyle(SMALL_FONT,HORIZ_DIR,8);
- settextjustify(CENTER_TEXT,TOP_TEXT);
- moveto(getmaxx() / 2,getmaxy() / 2);
- GC.cputs("Goodbye time - \r\n");
- GC.cputs("consuming graphic\r\n");
- GC.cputs("text programming!\r\n");
- GC.cputs("\n");
- GC.cputs("Press any key to continue ...");
- GC.getch();
- closegraph();
-
- puts("If you find gconio useful and are using it in your");
- puts("applications, how about telling a friend about it.");
- puts("Gconio is freeware - I only ask that you leave my");
- puts("copyright notice untouched! I will try to answer");
- puts("as many of your questions and/or comments (time ");
- puts("and money permitting). Thanks! John CIS: 73757,2233");
- puts("");
- puts("PSW / Power SoftWare");
- puts("P.O. Box 10072");
- puts("McLean, Virginia 22102 8072");
- puts("(703) 759-3838");
- puts("");
- puts("That's all folks!");
- puts("");
- puts("Press enter to quit.");
- getchar();
- }
-
- #endif