#include #include "keyboard.h" #include "colors.h" #include "screen.h" #define ATEQU Attribute = (Bold + Blink + Fore + (Back << 4)) #define COLOR Attribute static char far* Video; static char far* Next; static int Row; static int Col; static int WinTop; static int WinBottom; static int Attribute; static int Fore = LIGHTGRAY; static int Back = BLACK; static int Scroll = -1; static int UpdateCursor = 1; static unsigned Blink = 0; static unsigned Bold = 0; static int Wrap = 0; static int BW = 0; static int LastRow = 24; static int LastCol = 79; void SCR_Init() { union REGS r; int i; r.h.ah = 0x0f; int86( 0x10, &r, &r ); if( r.h.al == 0 || r.h.al == 2 || r.h.al == 7 ) BW = 1; int86( 0x11, &r, &r ); if( (r.h.al & 0x30) == 0x30 ) Video = (char far *) 0xB0000000L; else Video = (char far *) 0xB8000000L; LastRow = 24; LastCol = 79; WinTop = 0; WinBottom = LastRow; Bold = 0; Blink = 0; Fore = LIGHTGRAY; Back = BLACK; ATEQU; Scroll = -1; SCR_LineCursor(); SCR_Clear( 0 ); SCR_GotoRowCol( 0, 0, 0 ); } SCR_Term() { } SCR_SetScreenHeight( int h ) { if( h < 2 ) h = 2; else if( h > 25 ) h = 25; LastRow = h - 1; } SCR_SetScreenWidth( int w ) { if( w < 2 ) w = 2; else if( w > 80 ) w = 80; LastCol = w - 1; } int SCR_IsColor() { return !BW; } void SCR_ScrollColor( int c ) { Scroll = c; } void SCR_ClearArea( int l, int t, int r, int b ) { union REGS regs; regs.h.ah = 0x06; regs.h.al = b - t + 1; regs.h.bh = Scroll == -1 ? COLOR : Scroll; regs.x.cx = (t << 8) + l; regs.x.dx = (b << 8) + r; int86( 0x10, ®s, ®s ); } void SCR_Fill( int l, int t, int r, int b, int ch, int co ) { register j, i; char far* v = Video; for( i = t; i <= b; i++ ) { v = Video + (l << 1) + i * 160; for( j = l; j <= r; j++ ) { *v++ = ch; *v++ = co; } } } void SCR_FillArea( int l, int t, int r, int b ) { union REGS regs; regs.h.ah = 0x06; regs.h.al = b - t + 1; regs.h.bh = COLOR; regs.x.cx = (t << 8) + l; regs.x.dx = (b << 8) + r; int86( 0x10, ®s, ®s ); } void SCR_Clear( int w ) { union REGS regs; regs.h.ah = 0x06; regs.h.al = (w ? (WinBottom - WinTop + 1) : (LastRow + 1)); regs.h.bh = Scroll == -1 ? COLOR : Scroll; regs.x.cx = (w ? (WinTop << 8) : 0); regs.x.dx = (w ? (WinBottom << 8) : ((LastRow << 8) + LastCol) ); int86( 0x10, ®s, ®s ); } void SCR_ClearEOL() { register i; char far* v; v = Video + Row * 160 + (Col << 1); for( i = Col; i <= LastCol; i++ ) { *v++ = ' '; *v++ = Scroll == -1 ? COLOR : Scroll; } } void SCR_ClearBOL() { register i; char far* v; v = Video + Row * 160; for( i = 0; i <= Col; i++ ) { *v++ = ' '; *v++ = Scroll == -1 ? COLOR : Scroll; } } void SCR_ClearBOD( int w ) { SCR_ClearBOL( w ); if( w ) SCR_ClearArea( 0, WinTop, LastCol, Row - 1 ); else SCR_ClearArea( 0, 0, LastCol, Row - 1 ); } void SCR_ClearEOD( int w ) { SCR_ClearEOL( w ); if( w ) SCR_ClearArea( 0, Row + 1, LastCol, WinBottom ); else SCR_ClearArea( 0, Row + 1, LastCol, LastRow ); } SCR_InsertChar( int n, int c ) { char far* v; int l; if( n < 1 ) n = 1; else if( n > 80 ) n = 80; while( n-- ) { v = Video + Row * 160 + 159; for( l = Col; l < 79; l++ ) { *v = *(v - 2); v--; *v = *(v - 2); v--; } *v-- = Scroll == -1 ? COLOR : Scroll; *v-- = c; } } SCR_DeleteChar( int n ) { char far* v; int l; if( n < 1 ) n = 1; else if( n > 80 ) n = 80; while( n-- ) { v = Video + Row * 160 + (Col << 1); for( l = Col; l < 79; l++ ) { *v = *(v + 2); v++; *v = *(v + 2); v++; } *v++ = ' '; *v++ = Scroll == -1 ? COLOR : Scroll; } } void SCR_EraseChars( int n ) { char far* v; if( n < 1 ) n = 1; v = Video + Row * 160 + (Col << 1); while( n-- ) { *v++ = ' '; *v++ = Scroll == -1 ? COLOR : Scroll; } } void SCR_InsertLine( int w, int n ) { if( n < 1 ) n = 1; if( w ) SCR_ScrollArea( SCROLL_DOWN, 0, Row, 79, WinBottom, n ); else SCR_ScrollArea( SCROLL_DOWN, 0, Row, LastCol, LastRow, n ); } void SCR_DeleteLine( int w, int n ) { if( n < 1 ) n = 1; if( w ) SCR_ScrollArea( SCROLL_UP, 0, Row, 79, WinBottom, n ); else SCR_ScrollArea( SCROLL_UP, 0, Row, LastCol, LastRow, n ); } void SCR_ScrollArea( int dir, int l, int t, int r, int b, int n ) { union REGS regs; if( n < 1 ) n = 1; else if( n > 1 + b - t ) n = 1 + b - t; regs.h.ah = dir; regs.h.al = n; regs.h.bh = ((Scroll == -1) ? COLOR : Scroll); regs.x.cx = (t << 8) + l; regs.x.dx = (b << 8) + r; int86( 0x10, ®s, ®s ); } void SCR_Scroll( int w, int dir, int n ) { union REGS regs; regs.h.ah = dir; regs.h.al = n; regs.h.bh = ((Scroll == -1) ? COLOR : Scroll); regs.x.cx = (w ? (WinTop << 8) : 0); regs.x.dx = (w ? ((WinBottom << 8) + 79) : 0x194f); int86( 0x10, ®s, ®s ); } void SCR_DefineRegion( int t, int b ) { if( t < 0 ) t = 0; if( t > LastRow - 1 ) t = LastRow - 1; if( b <= t ) b = t + 1; if( b > LastRow ) b = LastRow; WinTop = t; WinBottom = b; } int SCR_GetTop() { return WinTop; } int SCR_GetBottom() { return WinBottom; } void SCR_PutCursor( int w, int r, int c ) { union REGS regs; if( r < 0 ) r = 0; else if( r > (w ? (WinBottom - WinTop) : LastRow) ) r = (w ? (WinBottom - WinTop) : LastRow); if( c < 0 ) c = 0; else if( c > 79 ) c = 79; regs.h.ah = 0x02; regs.h.bh = 0x00; regs.h.dh = r; regs.h.dl = c; int86( 0x10, ®s, ®s ); } void SCR_GotoRowCol( int w, int r, int c ) { if( r < 0 ) r = 0; else if( r > (w ? (WinBottom - WinTop) : LastRow) ) r = (w ? (WinBottom - WinTop) : LastRow); if( c < 0 ) c = 0; else if( c > 79 ) c = 79; Row = (w ? (WinTop + r) : r); Col = c; Next = (Video + Row * 160 + (Col << 1)); if( UpdateCursor ) SCR_PutCursor( w, r, c ); } int SCR_MoveLeft( int n ) { if( Col == 0 ) return 0; if( n < 1 ) n = 1; Col -= n; if( Col < 0 ) Col = 0; SCR_GotoRowCol( 0, Row, Col ); return 1; } int SCR_MoveRight( int n ) { if( Col == 79 ) return 0; if( n < 1 ) n = 1; Col += n; if( Col > 79 ) Col = 79; SCR_GotoRowCol( 0, Row, Col ); return 1; } int SCR_MoveUp( int n ) { if( Row == WinTop || Row == 0 ) return 0; if( n < 1 ) n = 1; while( n-- && Row != WinTop && Row != 0 ) Row--; SCR_GotoRowCol( 0, Row, Col ); return 1; } int SCR_MoveDown( int n ) { if( Row == WinBottom || Row == LastRow ) return 0; if( n < 1 ) n = 1; while( n-- && Row != WinBottom && Row != LastRow ) Row++; SCR_GotoRowCol( 0, Row, Col ); return 1; } int SCR_GetRow( int w ) { return (w ? (Row - WinTop) : Row); } int SCR_GetCol() { return Col; } void SCR_Wrap( int o ) { if( o ) Wrap = 1; else Wrap = 0; } void SCR_SetBlink( int o ) { if( o ) Blink = 128; else Blink = 0; ATEQU; } int SCR_GetBlink() { return Blink > 0; } void SCR_SetBold( int o ) { if( o ) Bold = 8; else Bold = 0; ATEQU; } int SCR_GetBold() { return Bold > 0; } void SCR_SetFore( int c ) { if( c < 0 ) c = 0; else if( c > 7 ) { if( c > 15 ) c = 15; c -= 8; } Fore = c; ATEQU; } int SCR_GetFore() { return Fore; } void SCR_SetBack( int c ) { if( c < 0 ) c = 0; else if( c > 7 ) { if( c > 15 ) c = 15; c -= 8; } Back = c; ATEQU; } int SCR_GetBack() { return Back; } void SCR_SetColor( int c ) { Blink = (c & 128); Bold = (c & 8); Fore = (c & 7); Back = (c & 112) >> 4; ATEQU; } int SCR_GetColor() { return COLOR; } void SCR_PutChar( int w, unsigned char c ) { if( Col > 79 ) { if( Wrap ) { Col = 0; Row++; if( Row == (w ? WinBottom : LastRow) + 1 ) { Row = (w ? WinBottom : LastRow); SCR_Scroll( w, SCROLL_UP, 1 ); } } else Col = 79; Next = (Video + Row * 160 + (Col << 1)); } if( c < 32 ) switch( c ) { case 0 : return; case 7 : sound( 700 ); delay( 100 ); nosound(); delay( 10 ); return; case 8 : if( Col > 0 ) SCR_GotoRowCol( 0, Row, Col - 1 ); return; case 9 : SCR_PutString( 0, " " ); return; case 10 : case 11 : case 12 : if( Row == (w ? WinBottom : LastRow) ) SCR_Scroll( w, SCROLL_UP, 1 ); else SCR_GotoRowCol( 0, Row + 1, Col ); return; case 13 : SCR_GotoRowCol( 0, Row, 0 ); return; } *Next++ = c; *Next++ = COLOR; Col++; if( UpdateCursor ) SCR_PutCursor( 0, Row, Col ); } void SCR_PutString( int w, char* s ) { UpdateCursor = 0; while( *s ) SCR_PutChar( w, *s++ ); UpdateCursor = 1; SCR_GotoRowCol( 0, Row, Col ); } SCR_PutStringPad( int w, char* s, int p ) { UpdateCursor = 0; while( *s && p ) { SCR_PutChar( w, *s++ ); p--; } while( p-- ) SCR_PutChar( w, ' ' ); UpdateCursor = 1; SCR_GotoRowCol( 0, Row, Col ); } void SCR_DrawBorder( int l, int t, int r, int b, int bc, char* title, int tc ) { char far* v; int i; v = Video + t * 160 + (l << 1); *v++ = 'Ú'; *v++ = bc; i = l + 1; if( title ) { *v++ = '´'; *v++ = bc; *v++ = ' '; *v++ = tc; i += 2; while( *title ) { *v++ = *title++; *v++ = tc; i++; } *v++ = ' '; *v++ = tc; *v++ = 'Ã'; *v++ = bc; i += 2; } while( i++ < r ) { *v++ = 'Ä'; *v++ = bc; } *v++ = '¿'; *v++ = bc; v = Video + t * 160 + (l << 1) + 160; for( i = t + 1; i < b; i++ ) { *v = '³'; *(v + 1) = bc; *(v + ((r - l) << 1)) = '³'; *(v + ((r - l) << 1) + 1) = bc; v += 160; } *v++ = 'À'; *v++ = bc; for( i = l + 1; i < r; i++ ) { *v++ = 'Ä'; *v++ = bc; } *v++ = 'Ù'; *v = bc; } SCR_SaveArea( int l, int t, int b, int r, char* buf ) { char far* v; int x, y; for( y = t; y <= b; y++ ) { v = Video + y * 160 + (l << 1); for( x = l; x <= r; x++ ) { *buf++ = *v++; *buf++ = *v++; } } } SCR_RestoreArea( int l, int t, int b, int r, char* buf ) { char far* v; int x, y; for( y = t; y <= b; y++ ) { v = Video + y * 160 + (l << 1); for( x = l; x <= r; x++ ) { *v++ = *buf++; *v++ = *buf++; } } } SCR_SaveScreen( SCRSAV* s ) { register i; char far* v = Video; s->row = Row; s->col = Col; s->scroll = Scroll; s->fore = Fore; s->back = Back; s->blink = Blink; s->bold = Bold; s->wrap = Wrap; s->top = WinTop; s->bottom = WinBottom; for( i = 0; i < 4000; i++ ) s->buffer[i] = *v++; } SCR_RestoreScreen( SCRSAV* s ) { register i; char far* v = Video; Row = s->row; Col = s->col; Scroll = s->scroll; Fore = s->fore; Back = s->back; Blink = s->blink; Bold = s->bold; Wrap = s->wrap; WinTop = s->top; WinBottom = s->bottom; for( i = 0; i < 4000; i++ ) *v++ = s->buffer[i]; SCR_GotoRowCol( 0, Row, Col ); ATEQU; } SCR_NoCursor() { union REGS regs; regs.h.ah = 0x01; regs.h.ch = 0x20; int86( 0x10, ®s, ®s ); } SCR_BlockCursor() { union REGS regs; regs.h.ah = 0x01; regs.h.ch = 0; regs.h.cl = 11; int86( 0x10, ®s, ®s ); } SCR_LineCursor() { union REGS regs; regs.h.ah = 0x01; regs.h.ch = 10; regs.h.cl = 11; int86( 0x10, ®s, ®s ); } SCR_GetString( char* s, int l ) { int done, k, i, c, ins = 1; c = Col; i = strlen( s ); while( i < l ) s[i++] = ' '; s[i] = 0; i = 0; SCR_PutString( 0, s ); SCR_GotoRowCol( 0, Row, c + i ); done = 0; SCR_LineCursor(); while( !done ) { SCR_GotoRowCol( 0, Row, c + i ); k = KEY_GetKey( 0 ); switch( k ) { case ESCAPE : done = -1; break; case ENTER : done = 1; break; case INSERT : ins = 1 - ins; if( ins ) SCR_LineCursor(); else SCR_BlockCursor(); break; case BACKSPACE : if( i == 0 ) break; i--; Col--; Next -= 2; case DELETE : memmove( &s[i], &s[i + 1], l - i - 1 ); s[l - 1] = ' '; SCR_PutString( 0, &s[i] ); break; case LEFT : if( i ) i--; break; case RIGHT : if( i < l ) i++; break; case HOME : i = 0; break; case END : i = l - 1; while( i && s[i] == ' ' ) i--; if( s[i] != ' ' ) i++; if( i > l ) i = l; break; default : if( k && k < 256 && i < l ) { if( ins ) memmove( &s[i + 1], &s[i], l - i - 1 ); s[i] = k; SCR_PutString( 0, &s[i] ); i++; } break; } } i = l - 1; while( i >= 0 && s[i] == ' ' ) s[i--] = 0; SCR_LineCursor(); return done; }