From bff066357e1fadbc1d32b1648bf791030e2acda0 Mon Sep 17 00:00:00 2001 From: jwalz Date: Sat, 5 Jan 2002 21:05:57 +0000 Subject: [PATCH] *** empty log message *** --- sys/msdos/vidtxt.c | 481 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 481 insertions(+) create mode 100644 sys/msdos/vidtxt.c diff --git a/sys/msdos/vidtxt.c b/sys/msdos/vidtxt.c new file mode 100644 index 000000000..b1b075a0e --- /dev/null +++ b/sys/msdos/vidtxt.c @@ -0,0 +1,481 @@ +/* SCCS Id: @(#)vidtxt.c 3.3 94/04/04 */ +/* Copyright (c) NetHack PC Development Team 1993 */ +/* NetHack may be freely redistributed. See license for details. */ +/* */ +/* + * vidtxt.c - Textmode video hardware support (BIOS and DJGPPFAST) + * + *Edit History: + * Initial Creation M. Allison 93/04/04 + * Add djgpp support K. Smolkowski 93/04/26 + * Add runtime monoadapter check M. Allison 93/05/09 + */ + +#define VIDEO_TEXT + +#include "hack.h" +#include "pcvideo.h" +#include "wintty.h" + +#include +#include + +#if defined(_MSC_VER) +# if _MSC_VER >= 700 +#pragma warning(disable:4018) /* signed/unsigned mismatch */ +#pragma warning(disable:4127) /* conditional expression is constant */ +#pragma warning(disable:4131) /* old style declarator */ +#pragma warning(disable:4305) /* prevents complaints with MK_FP */ +#pragma warning(disable:4309) /* initializing */ +#pragma warning(disable:4759) /* prevents complaints with MK_FP */ +# endif +#endif + +/* void FDECL(txt_xputc,(char, int)); */ /* write out character (and attribute) */ + +extern int attrib_text_normal; /* text mode normal attribute */ +extern int attrib_gr_normal; /* graphics mode normal attribute */ +extern int attrib_text_intense; /* text mode intense attribute */ +extern int attrib_gr_intense; /* graphics mode intense attribute */ + +#ifdef OVLB + +void +txt_get_scr_size() +{ + union REGS regs; + + if (!iflags.BIOS) { + CO = 80; + LI = 24; + return; + } + +# ifdef PC9800 + regs.h.ah = SENSEMODE; + (void) int86(CRT_BIOS, ®s, ®s); + + CO = (regs.h.al & 0x02) ? 40 : 80; + LI = (regs.h.al & 0x01) ? 20 : 25; +# else + regs.x.ax = FONTINFO; + regs.x.bx = 0; /* current ROM BIOS font */ + regs.h.dl = 24; /* default row count */ + /* in case no EGA/MCGA/VGA */ + (void) int86(VIDEO_BIOS, ®s, ®s); /* Get Font Information */ + + /* MDA/CGA/PCjr ignore INT 10h, Function 11h, but since we + * cleverly loaded up DL with the default, everything's fine. + * + * Otherwise, DL now contains rows - 1. Also, CX contains the + * points (bytes per character) and ES:BP points to the font + * table. -3. + */ + + regs.h.ah = GETMODE; + (void) int86(VIDEO_BIOS, ®s, ®s); /* Get Video Mode */ + + /* This goes back all the way to the original PC. Completely + * safe. AH contains # of columns, AL contains display mode, + * and BH contains the active display page. + */ + + LI = regs.h.dl + 1; + CO = regs.h.ah; +# endif /* PC9800 */ +} +#endif /*OVLB*/ + +/* + * -------------------------------------------------------------- + * The rest of this file is only compiled if NO_TERMS is defined. + * -------------------------------------------------------------- + */ + +#ifdef NO_TERMS +/* #include "wintty.h" */ + +# ifdef SCREEN_DJGPPFAST +#include +#include +# endif + +void FDECL(txt_gotoxy, (int,int)); + +# if defined(SCREEN_BIOS) && !defined(PC9800) +void FDECL(txt_get_cursor, (int *, int *)); +# endif + +# ifdef SCREEN_DJGPPFAST +#define txt_get_cursor(x,y) ScreenGetCursor(y,x) +# endif + +extern int g_attribute; /* Current attribute to use */ +extern int monoflag; /* 0 = not monochrome, else monochrome */ + +# ifdef OVLB +void +txt_backsp() +{ +# ifdef PC9800 + union REGS regs; + + regs.h.dl = 0x01; /* one column */ + regs.h.ah = CURSOR_LEFT; + regs.h.cl = DIRECT_CON_IO; + + int86(DOS_EXT_FUNC, ®s, ®s); + + txt_xputc(' ',attrib_text_normal); + + regs.h.dl = 0x01; /* one column */ + regs.h.ah = CURSOR_LEFT; + regs.h.cl = DIRECT_CON_IO; + + (void) int86(DOS_EXT_FUNC, ®s, ®s); +# else + int col,row; + + txt_get_cursor(&col, &row); + if (col > 0) col = col-1; + txt_gotoxy(col,row); + txt_xputc(' ',attrib_text_normal); + txt_gotoxy(col,row); +# endif +} + +void +txt_nhbell() +{ + union REGS regs; + + if (flags.silent) return; + regs.h.dl = 0x07; /* bell */ + regs.h.ah = 0x02; /* Character Output function */ + (void) int86(DOSCALL, ®s, ®s); +} +# endif /* OVLB */ + +# ifdef OVL0 +void +txt_clear_screen() +/* djgpp provides ScreenClear(), but in version 1.09 it is broken + * so for now we just use the BIOS Routines + */ +{ + union REGS regs; +# ifdef PC9800 + regs.h.dl = attr98[attrib_text_normal]; + regs.h.ah = SETATT; + regs.h.cl = DIRECT_CON_IO; + + (void) int86(DOS_EXT_FUNC, ®s, ®s); + + regs.h.dl = 0x02; /* clear whole screen */ + regs.h.ah = SCREEN_CLEAR; + regs.h.cl = DIRECT_CON_IO; + + (void) int86(DOS_EXT_FUNC, ®s, ®s); +# else + regs.h.dl = (char)(CO - 1); /* columns */ + regs.h.dh = (char)(LI - 1); /* rows */ + regs.x.cx = 0; /* CL,CH = x,y of upper left */ + regs.x.ax = 0; + regs.x.bx = 0; + regs.h.bh = (char)attrib_text_normal; + regs.h.ah = (char)SCROLL; + /* DL,DH = x,y of lower rt */ + (void) int86(VIDEO_BIOS, ®s, ®s); /* Scroll or init window */ + txt_gotoxy(0,0); +# endif +} + +void +txt_cl_end(col,row) /* clear to end of line */ +int col,row; +{ + union REGS regs; +# ifndef PC9800 + int count; +# endif + +# ifdef PC9800 + regs.h.dl = attr98[attrib_text_normal]; + regs.h.ah = SETATT; + regs.h.cl = DIRECT_CON_IO; + + (void) int86(DOS_EXT_FUNC, ®s, ®s); + + regs.h.dl = 0x00; /* clear to end of line */ + regs.h.ah = LINE_CLEAR; + regs.h.cl = DIRECT_CON_IO; + + (void) int86(DOS_EXT_FUNC, ®s, ®s); +# else + count = CO - col; + txt_gotoxy(col,row); + regs.h.ah = PUTCHARATT; /* write attribute & character */ + regs.h.al = ' '; /* character */ + regs.h.bh = 0; /* display page */ + /* BL = attribute */ + regs.h.bl = (char)attrib_text_normal; + regs.x.cx = count; + if (count != 0) + (void) int86(VIDEO_BIOS, ®s, ®s); /* write attribute + & character */ +# endif +} + +void +txt_cl_eos() /* clear to end of screen */ +{ + union REGS regs; +# ifndef PC9800 + int col,row; +# endif + +# ifdef PC9800 + regs.h.dl = attr98[attrib_text_normal]; + regs.h.ah = SETATT; + regs.h.cl = DIRECT_CON_IO; + + (void) int86(DOS_EXT_FUNC, ®s, ®s); + + regs.h.dl = 0x00; /* clear to end of screen */ + regs.h.ah = SCREEN_CLEAR; + regs.h.cl = DIRECT_CON_IO; + + (void) int86(DOS_EXT_FUNC, ®s, ®s); +# else + txt_get_cursor(&col, &row); + txt_cl_end(col,row); /* clear to end of line */ + txt_gotoxy(0,(row < (LI-1) ? row+1 : (LI-1))); + regs.h.dl = (char) (CO-1); /* X of lower right */ + regs.h.dh = (char) (LI-1); /* Y of lower right */ + regs.h.cl = 0; /* X of upper left */ + /* Y (row) of upper left */ + regs.h.ch = (char) (row < (LI-1) ? row+1 :(LI-1)); + regs.x.cx = 0; + regs.x.ax = 0; + regs.x.bx = 0; + regs.h.bh = (char)attrib_text_normal; + regs.h.ah = SCROLL; + (void) int86(VIDEO_BIOS, ®s, ®s); /* Scroll or initialize window */ +# endif +} +# endif /* OVL0 */ + +# ifdef OVLB +void +txt_startup(wid, hgt) + int *wid, *hgt; +{ + txt_get_scr_size(); + *wid = CO; + *hgt = LI; + + attrib_gr_normal = attrib_text_normal; + attrib_gr_intense = attrib_text_intense; + g_attribute = attrib_text_normal; /* Give it a starting value */ +} +# endif /* OVLB */ + +/* + * Screen output routines (these are heavily used). + * + * These are the 3 routines used to place information on the screen + * in the NO_TERMS PC tty port of NetHack. These are the routines + * that get called by routines in other NetHack source files (such + * as those in win/tty). + * + * txt_xputs - Writes a c null terminated string at the current location. + * Depending on compile options, this could just be a series + * of repeated calls to xputc() for each character. + * txt_xputc - Writes a single character at the current location. Since + * various places in the code assume that control characters + * can be used to control, we are forced to interpret some of + * the more common ones, in order to keep things looking correct. + * + * NOTES: + * wintty.h uses macros to redefine common output functions + * such as puts, putc, putchar, so that they get steered into + * either xputs (for strings) or xputc (for single characters). + * References to puts, putc, and putchar in other source files + * (that include wintty.h) are actually using these routines. + */ + +# ifdef OVL0 +void +txt_xputs(s,col,row) +const char *s; +int col,row; +{ + char c; + + if (s != (char *)0) { + while (*s != '\0') { + txt_gotoxy(col,row); + c = *s++; + txt_xputc(c,g_attribute); + if (col < (CO-1)) col++; + txt_gotoxy(col,row); + } + } +} + +void +txt_xputc(ch,attr) /* write out character (and attribute) */ +char ch; +int attr; +{ +# ifdef PC9800 + union REGS regs; + + regs.h.dl = attr98[attr]; + regs.h.ah = SETATT; + regs.h.cl = DIRECT_CON_IO; + + (void) int86(DOS_EXT_FUNC, ®s, ®s); + + if (ch == '\n') { + regs.h.dl = '\r'; + regs.h.ah = PUTCHAR; + regs.h.cl = DIRECT_CON_IO; + + (void) int86(DOS_EXT_FUNC, ®s, ®s); + } + regs.h.dl = ch; + regs.h.ah = PUTCHAR; + regs.h.cl = DIRECT_CON_IO; + + (void) int86(DOS_EXT_FUNC, ®s, ®s); +# else +# ifdef SCREEN_BIOS + union REGS regs; +# endif + int col,row; + + txt_get_cursor(&col,&row); + switch(ch) { + case '\n': +#if 0 + col = 0; + ++row; +#endif + break; + default: +# ifdef SCREEN_DJGPPFAST + ScreenPutChar((int)ch,attr,col,row); +# endif +# ifdef SCREEN_BIOS + regs.h.ah = PUTCHARATT; /* write att & character */ + regs.h.al = ch; /* character */ + regs.h.bh = 0; /* display page */ + regs.h.bl = (char)attr; /* BL = attribute */ + regs.x.cx = 1; /* one character */ + (void) int86(VIDEO_BIOS, ®s, ®s); +# endif + if (col < (CO -1 )) ++col; + break; + } /* end switch */ + txt_gotoxy(col,row); +# endif /* PC9800 */ +} +# endif /* OVL0 */ + +/* + * This marks the end of the general screen output routines that are + * called from other places in NetHack. + * --------------------------------------------------------------------- + */ + +/* + * Cursor location manipulation, and location information fetching + * routines. + * These include: + * + * txt_get_cursor(x,y) - Returns the current location of the cursor. In + * some implementations this is implemented as a + * function (BIOS), and in others it is a macro + * (DJGPPFAST). + * + * txt_gotoxy(x,y) - Moves the cursor on screen to the specified x and + * y location. This routine moves the location where + * screen writes will occur next, it does not change + * the location of the player on the NetHack level. + */ + +# ifdef OVL0 +# if defined(SCREEN_BIOS) && !defined(PC9800) +/* + * This is implemented as a macro under DJGPPFAST. + */ +void +txt_get_cursor(x,y) /* get cursor position */ +int *x, *y; +{ + union REGS regs; + + regs.x.dx = 0; + regs.h.ah = GETCURPOS; /* get cursor position */ + regs.x.cx = 0; + regs.x.bx = 0; + (void) int86(VIDEO_BIOS, ®s, ®s); /* Get Cursor Position */ + *x = regs.h.dl; + *y = regs.h.dh; +} +# endif /* SCREEN_BIOS && !PC9800 */ + +void +txt_gotoxy(x,y) +int x,y; +{ +# ifdef SCREEN_BIOS + union REGS regs; + +# ifdef PC9800 + regs.h.dh = (char)y; /* row */ + regs.h.dl = (char)x; /* column */ + regs.h.ah = SETCURPOS; + regs.h.cl = DIRECT_CON_IO; + (void) int86(DOS_EXT_FUNC, ®s, ®s); /* Set Cursor Position */ +# else + regs.h.ah = SETCURPOS; + regs.h.bh = 0; /* display page */ + regs.h.dh = (char)y; /* row */ + regs.h.dl = (char)x; /* column */ + (void) int86(VIDEO_BIOS, ®s, ®s); /* Set Cursor Position */ +# endif +# endif +# if defined(SCREEN_DJGPPFAST) + ScreenSetCursor(y,x); +# endif + /* The above, too, goes back all the way to the original PC. If + * we ever get so fancy as to swap display pages (i doubt it), + * then we'll need to set BH appropriately. This function + * returns nothing. -3. + */ +} +# endif /* OVL0 */ + +/* + * This marks the end of the cursor manipulation/information routines. + * ------------------------------------------------------------------- + */ + +# ifdef OVLB +# ifdef MONO_CHECK +int txt_monoadapt_check() +{ + union REGS regs; + + regs.h.al = 0; + regs.h.ah = GETMODE; /* get video mode */ + (void) int86(VIDEO_BIOS, ®s, ®s); + return (regs.h.al == 7) ? 1 : 0; /* 7 means monochrome mode */ +} +# endif /* MONO_CHECK */ +# endif /* OVLB */ +#endif /* NO_TERMS */ + +/* vidtxt.c */