/* video.c - a few video subroutines to make writing C programs a bit simpler a line of code for printing something will look like this: at(2,20); in(RED,WHITE); cprintf("Just Like English!"); Of course, you can omit the at() or in() (or both) if you like. NOTE: Remember that you must somehow force VIDEO.C to recompile whenever you switch memory models. This is because I haven't specifically declared all the routines and variables as 'far' (I hate using extra space and code unless I have to). If you like, you can do so yourself, then you can link the same OBJ with any memory model. To use the following routines in your own program, just put the files video.c and video.hin your working directory, add the line '#include "video.h" to the top of your program, call initvideo() at the beginning of main(), and link video.obj with your main module. This has been tested, and runs without modification, on both Zortech C++ 1.0? and Turbo C 1.5. I don't know about other compilers or versions, but I imagine they shouldn't need much modification. As usual: permission granted to use this for whatever you want to, commercial, private, obscene, or otherwise. Laine Stump, 12/13/87 */ #include #include #include #include #include "video.h" typedef unsigned int WORD; typedef unsigned char BYTE; int curcolor; int currow, curcol; int scrrows, scrcols; WORD far *screen; char nibs[] = "0123456789ABCDEF"; int screenrows(void) { return(scrrows); } int screencols(void) { return(scrcols); } void scroll(int lines, int x1, int y1, int x2, int y2) { /* Scrolls the screen between x1,y1 and x2,y2. Scrolling is up if lines is positive, down if it is negative */ union REGS reg; if (lines < 0) { reg.h.ah = 7; lines = (-lines); } else reg.h.ah = 6; reg.h.al = lines; reg.h.bh = curcolor >> 8; reg.x.cx = (y1 << 8) + x1; reg.x.dx = (y2 << 8) + x2; int86(0x10, ®, ®); } /* scroll */ void cursorsize(int startline, int endline) { /* Sets the size of the cursor */ union REGS reg; reg.h.ah = 1; reg.x.cx = (startline << 8) + endline; int86(0x10, ®, ®); } /* cursorsize */ void clearscreen(void) { /* clears the screen to curcolor and positions cursor at(0,0) */ scroll(0, 0, 0, scrcols, scrrows); at(0,0); } /* clearscreen */ void cleareol(void) { /* clears from current position to end of line */ scroll(0,curcol, currow, scrcols, currow); } void at(int row, int col) { /* places the cursor at a specific row and column */ union REGS reg; currow = row; curcol = col; reg.h.ah = 2; reg.h.bh = 0; reg.x.dx = (row << 8) + col; int86(0x10, ®, ®); } /* at */ void in(char forecolor, char backcolor) { /* sets current color to 'color' */ curcolor = (forecolor | (backcolor << 4)) << 8; } /* in */ void cputc(char ch) { WORD far *ptr; *((WORD far *) (screen + (currow * scrcols) + curcol)) = ch+curcolor; at(currow, curcol+1); } /* cputc */ void cprintf(va_list arg_list, ...) /* Prints a string in video memory at current location in current color then advances cursor to end of string. This cprintf is functionally equivalent to the standard printf. the only difference is that it will use the color set by the function in(). (and that it is faster...) */ { va_list arg_ptr; char *format; char output[81]; BYTE* outptr; WORD far* scrptr; int ct, len; va_start(arg_ptr, arg_list); format = arg_list; vsprintf(output, format, arg_ptr); len = strlen(output); scrptr = screen + (currow * scrcols) + curcol; outptr = (BYTE *) output; for (ct = 0; ct < len; ct++) *scrptr++ = (*outptr++)+curcolor; at(currow,curcol+len); } /* cprintf */ void Write16Bytes (void* buf) { /* write the 16 bytes at *buf as hex digits, followed by the ASCII equivalent of same, at the curent cursor location. This routine is a bit specialized to have in a general purpose library, but I wanted faster screen paints. That's one of the advantages of writing your own library - you get to change it! */ int ct; BYTE* this; WORD far * scrptr; this = (BYTE *) buf; scrptr = (WORD far *) (screen + (currow * scrcols) + curcol); for(ct = 0; ct < 16; ct++) { *scrptr++ = nibs[(*(this)) >> 4]+curcolor; *scrptr++ = nibs[(*this++) & 0x0F]+curcolor; scrptr++; } this = buf; for(ct = 0; ct < 16; ct++) *scrptr++ = curcolor + (*this > 0x1F ? *(this++) : (*(this++),'.')); at(currow,curcol+65); } /* Write16Bytes */ void initvideo(void) { /* this should be called once at the beginning of the application */ union REGS reg; reg.h.ah = 15; int86(0x10, ®, ®); scrcols = reg.h.ah; scrrows = *((BYTE far *) MK_FP(0x0040,0x0084))+1; if (scrrows < 25) scrrows = 25; screen = (WORD far *)((reg.h.al != 7) ? 0xB8000000L : 0xB0000000L); in(LIGHTGRAY,BLACK); clearscreen(); } /* initvideo */ /*---- end of video.c ----*/