SCRNIO.C - Version 1
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> /* Anywhere the WIN32 define is tested, indicates an area that ** provides portability between 16-bit DOS and Win32 consoles. ** ** Since this is the screen IO module, and ANSI C does not support ** Color, non-buffered input, this module calls mostly non-ANSI, Intel-specific ** functions. */ #include "myio.h" #ifdef WIN32 static HANDLE hStdOut; static COORD Coord; static DWORD Written; static CONSOLE_CURSOR_INFO CursorInfo; static WORD ScreenBuffer[80*25]; /* Init - Initializes console data for a Win32 program (removed for DOS) */ void Init(void) { if( !hStdOut ) { if( (hStdOut=GetStdHandle(STD_OUTPUT_HANDLE)) == INVALID_HANDLE_VALUE) { perror( "Error initializing console"); exit(1); } GetConsoleCursorInfo( hStdOut, &CursorInfo ); } } #endif /* CPrintChar - Prints character 'Char', in color 'Color' */ void CPrintChar( int Char, int Color ) { #ifdef WIN32 if( !hStdOut) Init(); if( Char=='\b' ) { if( Coord.X--==0 ) /* Move Cursor */ { Coord.X=79; if( Coord.Y--==0 ) Coord.Y=0; } SetConsoleCursorPosition( hStdOut, Coord ); return; } CursorOn(); WriteConsoleOutputAttribute( hStdOut, (CONST WORD*)&Color, 1, Coord, &Written ); WriteConsoleOutputCharacter( hStdOut, (char*)&Char, 1, Coord, &Written ); if( Coord.X++==79 ) /* Move Cursor */ { Coord.X=0; if( Coord.Y++==25 ) Coord.Y=0; } SetConsoleCursorPosition( hStdOut, Coord ); #else union REGS Regin; Regin.h.al=(unsigned char )Char; if( Regin.h.al >= ' ' ) /* Don't print TAB or ENTER (or anything <' ') */ { /* in color, it displays odd characters */ Regin.h.ah=9; /* 9 = Print Character and Attribute */ Regin.h.bh=0; Regin.h.bl=(unsigned char)Color; Regin.x.cx=1; int86( 0x10, &Regin, &Regin ); } Regin.h.ah=0x0e; /* E = Print character (w/o Color), and move cursor */ int86( 0x10, &Regin, &Regin ); #endif } /* CPrintStr - Prints string 'Str', in color 'Color' */ void CPrintStr( char *Str, int Color ) { while( *Str ) CPrintChar( *Str++, Color ); } /* Locate - Moves cursor to screen coordinate Row, Col */ void Locate( int Row, int Col ) { #ifdef WIN32 Coord.X=(SHORT)Col; Coord.Y=(SHORT)Row; if( !hStdOut) Init(); SetConsoleCursorPosition( hStdOut, Coord ); #else union REGS Regin; Regin.h.ah=2; /* 2 = Set Cursor location */ Regin.h.bh=0; Regin.h.dh=(unsigned char) Row; Regin.h.dl=(unsigned char) Col; int86( 0x10, &Regin, &Regin ); #endif } /* GetLocation - Gets current cursor location, and stores it to Row and Col */ void GetLocation( int *Row, int *Col ) { #ifdef WIN32 *Row = Coord.Y; *Col = Coord.X; #else union REGS Regin; Regin.h.ah=3; /* 3 = Get Cursor location */ Regin.h.bh=0; int86( 0x10, &Regin, &Regin ); *Row = (int)Regin.h.dh; *Col = (int)Regin.h.dl; #endif } /* Cls - Clears the screen to the specified 'Color' value */ void Cls( int Color ) { #ifdef WIN32 int i; short Clr=(short)Color; Init(); Locate(0,0); for( i=0; i<80*25; i++ ) ScreenBuffer[i]=Clr; WriteConsoleOutputAttribute( hStdOut, ScreenBuffer, 80*25, Coord, &Written ); memset( ScreenBuffer, ' ', 80*25); WriteConsoleOutputCharacter( hStdOut, (char*)ScreenBuffer, 80*25, Coord, &Written ); #else union REGS Regin; Regin.h.ah=6; /* 6 = Scroll window up (clear window) */ Regin.h.al=0; Regin.h.bh=(unsigned char) Color; Regin.x.cx=0; /* ch,cl = row, column of upper-left corner */ Regin.x.dx=0x184F; /* dh,dl = row,column of lower-right corner */ int86( 0x10, &Regin, &Regin ); Locate(0,0); #endif } /* ClearRect - Clears out a rectangular region, with a specific color.*/ /* Row, Col - Determine upper left corner of rectangle on screen */ /* Height, Width - Determine size of rectangle */ void ClearRect( int Row, int Col, int Height, int Width, int Color ) { #ifdef WIN32 COORD Tmp; int i; Tmp.X=(SHORT)Col; //Row++; Height=Height+1; Width=Width+1; while( Height-- ) { Tmp.Y = (SHORT) (Row+Height); for( i=0; i <Width; i++ ) ScreenBuffer[i]=(short)Color; WriteConsoleOutputAttribute( hStdOut, ScreenBuffer, Width, Tmp, &Written ); memset( ScreenBuffer, ' ', Width ); WriteConsoleOutputCharacter( hStdOut, (char*)ScreenBuffer, Width, Tmp, &Written ); } #else union REGS Regin; Regin.h.ah=6; Regin.h.al=0; Regin.h.bl=0; Regin.h.bh=(unsigned char)Color; Regin.h.ch=Row; Regin.h.cl=Col; Regin.h.dh=Row+Height; Regin.h.dl=Col+Width; int86( 0x10, &Regin, &Regin ); #endif } /* Trim - Removes trailing whitespace from 'Str' */ void Trim( char *Str ) { char *End; for( End=Str+strlen(Str)-1; End >= Str && *End<=' '; End--) *End = '\0'; } /* GetKey - Inputs keys, including function keys. Returns their value */ /* Note: For normal keys, the value is their ASCII code. For special */ /* Keys like F1, Home, etc, the return value is their scan code (see */ /* .h file) */ int GetKey( void ) { int i; if( (i=getch())==0 || (i==0xE0) ) i=getch()*0x100; /* For 'special' keys. */ return(i); } /* GetStr - Inputs a string, with field-like editing ability */ /* Dest - Where to store result */ /* Len - Maximum length to input */ /* EColor - Edit Color. Editing takes place in this color */ /* RColor - String is re-drawn in this color when edits are done */ /* Options - one or more of the following: */ /* GS_INIT = Blank out string before editing */ /* GS_UPPR = Users text is converted to uppercase */ /* Note: This function will not wipe out previous data for Dest, */ /* unlike gets() does. */ int GetStr(char *Dest, int Len, int EColor, int RColor, int Options) { int CurPos, Row, Col, Ch; if( Options & GS_INIT ) /* Option Setting: Initial Dest to blank string */ *Dest='\0'; GetLocation( &Row, &Col ); /* Save starting screen location, needed later*/ Dest[Len]='\0'; /* Make sure Dest isn't already to long */ CurPos=strlen( Dest ); /*Make initial starting position the end of the str */ while( strlen( Dest ) < (unsigned int) Len ) /* Pad right with spaces to Len */ strcat( Dest, " "); CPrintStr( Dest, EColor ); Locate( Row, Col+CurPos ); while( (Ch=GetKey())!=ENTER && !IsGetStrExitKey(Ch) ) { if( Ch==BACKSPACE ) { if( CurPos ) { CPrintStr( "\b \b", EColor ); Dest[--CurPos]=' '; } continue; } if( CurPos == Len || IsFuncKey( Ch ) ) /* Ignore Function keys */ continue; if( Options & GS_UPPR ) /* Upper-case only option on? */ Ch=toupper(Ch); CPrintChar( Ch, EColor ); /* Store and Print character */ Dest[CurPos++]=(char)Ch; } Locate( Row, Col ); CPrintStr( Dest, RColor ); Trim( Dest ); /* Remove those right-side spaces */ return( Ch ); /* Return character used to terminate input */ } /* At - Displays string 'Str' in color 'Color, at location Row, Col */ void At( int Row, int Col, char *Str , int Color ) { Locate(Row,Col); CPrintStr( Str, Color ); } /* HideCursor - Hides cursor from screen */ void HideCursor() { #ifdef WIN32 CONSOLE_CURSOR_INFO Tmp=CursorInfo; if( !hStdOut ) Init(); Tmp.bVisible=FALSE; SetConsoleCursorInfo( hStdOut, &Tmp ); #else Locate(100,0); #endif } /* CursorHidden() - returns true if cursor is invisible, false if not */ int CursorHidden() { #ifdef WIN32 CONSOLE_CURSOR_INFO Tmp; GetConsoleCursorInfo( hStdOut, &Tmp); return( !Tmp.bVisible ); #else int X, Y; GetLocation( &Y, &X ); return( Y==100 ); #endif } #ifdef WIN32 /* CursorOn - Turns the cursor on. Automatically called by output routines*/ void CursorOn(void) { if( !hStdOut ) Init(); SetConsoleCursorInfo( hStdOut, &CursorInfo ); } #endif