/****************************************************************************** * Change Log * Date | Chnage *------------------------------------------------------------------------------ * 20-DEC-95 | JRJ Got rid of some ifdefs because Borland now supports _asm * 20-Dec-95 | JRJ Fixed text background color for Borland implementation * 20-Dec-95 | JRJ Changed sc_remappalette to call BIOS 0x10 subfunc 0x16 * (Borland implementation) ******************************************************************************/ #include "btypes.h" #include "scdspmsg.h" #include "color.h" #ifdef __BORLANDC__ #include #include /* #pragma inline */ #endif struct rccoord sc_gettextposition(); extern struct videoconfig video; #ifndef __BORLANDC__ #include "graph.h" #endif #define CURSOR_UNDERLINE 0 #define CURSOR_DOUBLE_UNDERLINE 1 #define CURSOR_BLOCK 2 static short cursortype = CURSOR_UNDERLINE; /**************************************************************************** * scdspmsg * Inputs: * unsigned char row: Row to display string * unsigned char col: Column to display string * unsigned char fore: Foreground color * unsigned char back: Background color * char * str: string to display * Result: void * * Effect: * Displays the string at the indicated position with the * indicated colors. Updates textposition ****************************************************************************/ void scdspmsg(unsigned char row, unsigned char col, unsigned char fore, unsigned char back, char * str) { char c; char a = (back << 4) + (fore & 0xF); struct rccoord xy; struct rccoord txy; xy = sc_gettextposition(); sc_settextposition(row+1,col+1); while(c = *str++) { /* emit each char */ /* Write character and attribute at cursor */ _asm { /* asm */ mov bh,0; /* page */ mov dh,row; mov dl, col; mov ah, 0x02; /* subfunction 02h: Set cursor pos */ int 0x10; mov ah, 0x09; /* subfunction 09h: Write char & attr */ mov al, c; /* character */ mov bh, 0; /* page */ mov bl, a; /* attribute */ mov cx, 1; /* one character */ int 0x10; /* video */ } /* asm */ sc_settextposition(row,++col); } /* emit each char */ } /**************************************************************************** * scattrib * Inputs: * unsigned char fore: foreground color * unsigned char back: background color * unsigned char c: Character to draw * short cnt: Replication factor * Result: void * * Effect: * Draws the character as indicated ****************************************************************************/ void scattrib(unsigned char fore, unsigned char back, unsigned char c, short cnt) { char a = (back << 4) + (fore & 0xF); _asm { /* asm */ mov ah,0x09; /* subfunction 09h */ mov al,c; /* character */ mov bh,0; /* page */ mov bl,a; /* attribute */ mov cx,cnt; /* rep characters */ int 0x10; /* video */ } /* asm */ } /**************************************************************************** * sc_setnormalcursor * Result: void * * Effect: * Sets a normal (underline or block) cursor, as specified by some * means we have not established ****************************************************************************/ void sc_setnormalcursor() { switch(cursortype) { /* which cursor */ case CURSOR_UNDERLINE: sc_settextcursor(SC_CURSOR_UNDERLINE); break; case CURSOR_DOUBLE_UNDERLINE: sc_settextcursor(SC_CURSOR_DOUBLE); break; case CURSOR_BLOCK: sc_settextcursor(SC_CURSOR_BLOCK); break; } /* which cursor */ } /**************************************************************************** * sc_setnocursor * Result: void * * Effect: * Turns off text cursor ****************************************************************************/ void sc_setnocursor() { sc_settextcursor(SC_CURSOR_NONE); } /**************************************************************************** * scscroll * Inputs: * unsigned char numlines: Number of lines to scroll * unsigned char color: Color attribute * unsigned char y0: upper left y-coordinate * unsigned char x0: upper left x-coordinate * unsigned char y1: lower right y-coordinate * unsigned char x1: lower right x-coordinate * unsigned char dir: direction, SCR_UP | SCR_DOWN * Result: void * * Effect: * Scrolls the window indicated by the coordinates given ****************************************************************************/ void scscroll(unsigned char numlines, unsigned char color, unsigned char y0, unsigned char x0, unsigned char y1, unsigned char x1, unsigned char dir) { /* ah 0x06 scroll up, 0x07 scroll down al # of lines, 0 to blank entire window bh attribute for blanked area ch upper left y-coordinate cl upper left x-coordinate dh lower right y-coordinate dl lower right x-coordinate */ _asm { mov ah, dir; mov al, numlines; mov bh, color; mov ch, y0; mov cl, x0; mov dh, y1; mov dl, x1; int 0x10; }; } /**************************************************************************** * scread * Inputs: * unsigned char * fore: foreground attribute * unsigned char * back: background attribute * Result: unsigned char * Character * Effect: * Reads the fore/background attributes of the current cursor position ****************************************************************************/ unsigned char scread(unsigned char * fore, unsigned char * back) { unsigned char a; unsigned char c; _asm{ mov ah,0x08; mov bh, 0; /* page */ int 0x10; /* read char and attribute */ mov a,ah; mov c,al; }; *fore = a & 0x0F; *back = a >> 4; return c; } /**************************************************************************** * sccurset * Inputs: * unsigned char row: * unsigned char col: * Result: void * * Effect: * Sets the cursor position ****************************************************************************/ void sccurset(unsigned char row, unsigned char col) { sc_settextposition(row+1, col+1); } /**************************************************************************** * sccurpos * Inputs: * unsigned char * row, unsigned char * col * Result: void * * Effect: * Gets the cursor position ****************************************************************************/ void sccurpos(unsigned char * row, unsigned char * col) { struct rccoord xy; xy = sc_gettextposition(); *row = xy.row - 1; *col = xy.col - 1; } /**************************************************************************** * scattribs * Inputs: * unsigned char color: Color to set in rectangle * unsigned char y0: Upper left y-coordinate * unsigned char x0: Upper left x-coordinate * unsigned char y1: Lower right y-coordinate * unsigned char x1: Lower right x-coordinate * Result: void * * Effect: * Sets attributes in the rectangle without changing the characters ****************************************************************************/ void scattribs(unsigned char color, unsigned char y0, unsigned char x0, unsigned char y1, unsigned char x1) { unsigned char x; unsigned char y; unsigned char old_x; unsigned char old_y; sccurpos(&old_y, &old_x); for(x = x0; x < x1; x++) for(y = y0; y < y1; y++) { /* fill chars */ _asm { mov ah, 0x02; /* set cursor position */ mov bh, 0; /* page */ mov dh, y; /* row */ mov dl, x; /* column */ int 0x10; /* do it */ mov ah, 0x08; /* read char & attribute */ mov bh, 0; /* page */ int 0x10; /* do it */ /* ah is attribute */ /* al is character */ mov ah, 0x09; /* set char & attribute */ mov bh,0; /* page */ mov bl,color; /* attribute to set */ mov cx,1; /* only for one character */ int 0x10; /* rewrite char with new attribute */ } } /* fill chars */ sccurset(old_y, old_x); } /**************************************************************************** * click * Result: void * * Effect: * Makes a "click" on the speaker to indicate a card column has * been "punched" ****************************************************************************/ void click() { /* NYI */ } /* sc_getvideoconfig - get video card information */ void sc_getvideoconfig(struct videoconfig *video) { #ifndef __BORLANDC__ _getvideoconfig(video); #endif #ifdef __BORLANDC__ struct text_info text_info; int gdriver,gmode; gettextinfo(&text_info); detectgraph(&gdriver,&gmode); video->numxpixels = 0; /* Indicating non graphics mode */ video->numypixels = 0; /* Indicating non graphics mode */ video->numtextcols = text_info.screenwidth; video->numtextrows = text_info.screenheight; video->numcolors = -1; /* Not used in this program */ video->bitsperpixel = -1; /* Not used in this program */ video->numvideopages = -1; /* Not used in this program */ video->mode = -1; /* Not used in this program */ video->adapter = gdriver; video->monitor = gdriver; video->memory = -1; #endif } /* Init video card (if necessary) */ int sc_init_graphics(void) { #ifndef __BORLANDC__ return(1); #endif #ifdef __BORLANDC__ return(1); #endif } /* routine to set video mode */ short sc_setvideomode(short mode) { #ifndef __BORLANDC__ return(_setvideomode(mode)); #endif #ifdef __BORLANDC__ int gdriver,gmode,grerror; detectgraph(&gdriver,&gmode); if((grerror = graphresult()) != grOk) { fprintf(stderr,"scdspmsg.c: Error %d in detectgraph.\n", grerror); return(0); } switch(mode) { case SC_C80: if(gdriver == HERCMONO || gdriver == EGAMONO) return(0); break; case SC_BW80: if(gdriver != HERCMONO && gdriver != EGAMONO) return(0); break; default: fprintf(stderr,"sc_setvideomode: unexpected mode: %d\n", mode); return(0); } textmode(mode); textbackground(BLACK); return(1); #endif } /* Routine to re-map color pallettes on EGA and VGA type adapters. */ short sc_remappalette(short index, long rgb) { #ifndef __BORLANDC__ return _remappalette(index,rgb); #endif #ifdef __BORLANDC__ int r,g,b,color; unsigned char do_index, do_color; switch(video.adapter) { case EGA: case VGA: color = (EGA_COLOR(RGB_R(rgb)) << 2) | (EGA_COLOR(RGB_G(rgb)) << 1) | EGA_COLOR(RGB_B(rgb)); /* setpalette(index,color); */ do_color = color; do_index = index; _asm { mov ah,0x10; /* Set palette registers */ mov al,0x00; /* set one register */ mov bh,do_color; /* color to use */ mov bl,do_index; /* color index */ int 0x10; /* just do it */ } /* if(graphresult != grOk) { return(-1); } */ break; case MCGA: case IBM8514: setrgbpalette(index, RGB_R(rgb) << 2, RGB_G(rgb) << 2, RGB_B(rgb) << 2); return(0); break; default: fprintf(stderr,"sc_remappalette: Invalid adapter: %d\n", video.adapter); return(-1); } return(0); #endif } /* Routine to put text out to console. This is here because the original progam used MicroSoft's _outtext, even though cputs probably would have worked OK. */ void sc_outtext(char *s) { #ifndef __BORLANDC__ _outtext(s); #endif #ifdef __BORLANDC__ cputs(s); #endif } /* Routine to set current text position */ void sc_settextposition(short row, short col) { #ifndef __BORLANDC__ _settextposition(row,col); #endif #ifdef __BORLANDC__ gotoxy(col,row); #endif } /* Routine to clear the screen */ void sc_clearscreen() { #ifndef __BORLANDC__ _clearscreen(_GCLEARSCREEN); #endif #ifdef __BORLANDC__ clrscr(); #endif } /* Routine to set cursor type */ void sc_settextcursor(short cursor) { #ifndef __BORLANDC__ _settextcursor(cursor); #endif #ifdef __BORLANDC__ _setcursortype(cursor); #endif } /* Routine to return the location of the cursor */ struct rccoord sc_gettextposition() { #ifndef __BORLANDC__ return(_gettextposition()); #endif #ifdef __BORLANDC__ static struct rccoord t; t.row = (short) wherex; t.col = (short) wherey; return(t); #endif } /* And, finally, a mouse routine, since we don't want everyone to need the library! */ void real_mouse(short *m1, short *m2, short *m3, short *m4) { short im1,im2,im3,im4; im1 = *m1; im2 = *m2; im3 = *m3; im4 = *m4; _asm { mov ax,im1 mov bx,im2 mov cx,im3 mov dx,im4 int 51 mov im1,ax mov im2,bx mov im3,cx mov im4,dx } *m1 = im1; *m2 = im2; *m3 = im3; *m4 = im4; }