diff options
Diffstat (limited to 'src/main-ibm.c')
-rw-r--r-- | src/main-ibm.c | 1594 |
1 files changed, 0 insertions, 1594 deletions
diff --git a/src/main-ibm.c b/src/main-ibm.c deleted file mode 100644 index 6201649c..00000000 --- a/src/main-ibm.c +++ /dev/null @@ -1,1594 +0,0 @@ -/* File: main-ibm.c */ - -/* - * Copyright (c) 1997 Ben Harrison, and others - * - * This software may be copied and distributed for educational, research, - * and not for profit purposes provided that this copyright and statement - * are included in all such copies. - */ - -/* Purpose: Visual Display Support for "term.c", for the IBM */ - -/* - * Original code by "Billy Tanksley (wtanksle@ucsd.edu)" - * Use "Makefile.ibm" to compile Angband using this file. - * - * Support for DJGPP v2 by "Scott Egashira (egashira@u.washington.edu)" - * - * Extensive modifications by "Ben Harrison (benh@phial.com)", - * including "collation" of the Watcom C/C++ and DOS-286 patches. - * - * Watcom C/C++ changes by "David Boeren (akemi@netcom.com)" - * Use "Makefile.wat" to compile this file with Watcom C/C++, and - * be sure to define "USE_IBM" and "USE_WAT". - * - * DOS-286 (conio.h) changes by (Roland Jay Roberts (jay@map.com) - * Use "Makefile.286" (not ready) to compile this file for DOS-286, - * and be sure to define "USE_IBM", "USE_WAT", and "USE_286". Also, - * depending on your compiler, you may need to define "USE_CONIO". - * - * True color palette support by "Mike Marcelais (michmarc@microsoft.com)", - * with interface to the "color_table" array by Ben Harrison. - * - * Both "shift" keys are treated as "identical", and all the modifier keys - * (control, shift, alt) are ignored when used with "normal" keys, unless - * they modify the underlying "ascii" value of the key. You must use the - * new "user pref files" to be able to interact with the keypad and such. - * - * The "lib/user/pref-ibm.prf" file contains macro definitions and possible - * alternative color set definitions. The "lib/user/font-ibm.prf" contains - * attr/char mappings for walls and floors and such. - * - * Note the "Term_user_ibm()" function hook, which could allow the user - * to interact with the "main-ibm.c" visual system. Currently this hook - * is unused, but, for example, it could allow the user to toggle "sound" - * or "graphics" modes, or to select the number of screen rows, with the - * extra screen rows being used for the mirror window. - */ - - -#include "angband.h" - - -#ifdef USE_IBM - - -/* - * Use a "virtual" screen to "buffer" screen writes. - */ -#define USE_VIRTUAL - -#ifdef USE_DOSSOCK -#include <arpa/inet.h> -#include <netinet/in.h> -#include <sys/socket.h> -#include <netdb.h> -#endif - -#include <bios.h> -#include <dos.h> -#include <dir.h> - -#ifdef USE_WAT - -# include <conio.h> - -# ifdef USE_CONIO -# else /* USE_CONIO */ - -# include <graph.h> - -# define bioskey(C) _bios_keybrd(C) - -# endif /* USE_CONIO */ - -# ifndef USE_286 -# define int86(a, b, c) int386(a, b, c) -# endif - -# define inportb(x) inp(x) -# define outportb(x, y) outp(x, y) - -#else /* USE_WAT */ - -# if __DJGPP__ > 1 - -# include <pc.h> -# include <osfcn.h> - -# else /* __DJGPP__ > 1 */ -# ifdef __DJGPP__ -# error "Upgrade to version 2.0 of DJGPP" -# endif /* __DJGPP__ */ -# endif /* __DJGPP__ > 1 */ - -#endif /* USE_WAT */ - - -#ifdef USE_CONIO - -# include <conio.h> - -/* - * Hack -- write directly to video card - */ -extern int directvideo = 1; - -/* - * Hack -- no virtual screen - */ -# undef USE_VIRTUAL - -#endif /* USE_CONIO */ - - -/* - * Keypress input modifier flags (hard-coded by DOS) - */ -#define K_RSHIFT 0 /* Right shift key down */ -#define K_LSHIFT 1 /* Left shift key down */ -#define K_CTRL 2 /* Ctrl key down */ -#define K_ALT 3 /* Alt key down */ -#define K_SCROLL 4 /* Scroll lock on */ -#define K_NUM 5 /* Num lock on */ -#define K_CAPS 6 /* Caps lock on */ -#define K_INSERT 7 /* Insert on */ - - -/* - * Foreground color bits (hard-coded by DOS) - */ -#define VID_BLACK 0x00 -#define VID_BLUE 0x01 -#define VID_GREEN 0x02 -#define VID_CYAN 0x03 -#define VID_RED 0x04 -#define VID_MAGENTA 0x05 -#define VID_YELLOW 0x06 -#define VID_WHITE 0x07 - -/* - * Bright text (hard-coded by DOS) - */ -#define VID_BRIGHT 0x08 - -/* - * Background color bits (hard-coded by DOS) - */ -#define VUD_BLACK 0x00 -#define VUD_BLUE 0x10 -#define VUD_GREEN 0x20 -#define VUD_CYAN 0x30 -#define VUD_RED 0x40 -#define VUD_MAGENTA 0x50 -#define VUD_YELLOW 0x60 -#define VUD_WHITE 0x70 - -/* - * Blinking text (hard-coded by DOS) - */ -#define VUD_BRIGHT 0x80 - - -/* - * Screen Size - */ -static int rows = 25; -static int cols = 80; - - -/* - * Physical Screen - */ -#ifdef USE_286 -# define PhysicalScreen ((byte *)MK_FP(0xB800, 0x0000)) -#else -# define PhysicalScreen ((byte *)(0xB800 << 4)) -#endif - - -#ifdef USE_VIRTUAL - -/* - * Virtual Screen Contents - */ -static byte *VirtualScreen; - -#else - -/* -* Physical screen access -*/ -#define VirtualScreen PhysicalScreen - -#endif - - -/* - * Hack -- the cursor "visibility" - */ -static int saved_cur_v; -static int saved_cur_high; -static int saved_cur_low; - - -#ifdef USE_CONIO -#else /* USE_CONIO */ - -/* -* This array is used for "wiping" the screen -*/ -static byte wiper[160]; - -#endif /* USE_CONIO */ - - -/* - * The main screen (currently the only screen) - */ -static term term_screen_body; - - -/* - * Choose between the "complex" and "simple" color methods - */ -static byte use_color_complex = FALSE; - - -/* - * The "complex" color set - */ -static long ibm_color_complex[16]; - - -/* - * The "simple" color set - * - * This table is used by the "color" code to instantiate the "approximate" - * Angband colors using the only colors available on crappy monitors. - * - * The entries below are taken from the "color bits" defined above. - * - * Note that values from 16 to 255 are extremely ugly. - * - * The values below came from various sources, if you do not like them, - * get a better monitor, or edit "pref-ibm.prf" to use different codes. - * - * Note that many of the choices below suck, but so do crappy monitors. - */ -static byte ibm_color_simple[16] = -{ - VID_BLACK, /* Dark */ - VID_WHITE, /* White */ - VID_CYAN, /* Slate XXX */ - VID_RED | VID_BRIGHT, /* Orange XXX */ - VID_RED, /* Red */ - VID_GREEN, /* Green */ - VID_BLUE, /* Blue */ - VID_YELLOW, /* Umber XXX */ - VID_BLACK | VID_BRIGHT, /* Light Dark */ - VID_CYAN | VID_BRIGHT, /* Light Slate XXX */ - VID_MAGENTA, /* Violet */ - VID_YELLOW | VID_BRIGHT, /* Yellow */ - VID_MAGENTA | VID_BRIGHT, /* Light Red XXX */ - VID_GREEN | VID_BRIGHT, /* Light Green */ - VID_BLUE | VID_BRIGHT, /* Light Blue */ - VID_YELLOW /* Light Umber XXX */ -}; - - - -/* - * Activate the "ibm_color_complex" palette information. - * - * Code by Mike Marcelais, with help from "The programmer's guide - * to the EGA and VGA video cards" [Farraro]. - * - * On VGA cards, colors go through a double-indirection when looking - * up the `real' color when in 16 color mode. The color value in the - * attribute is looked up in the EGA color registers. Then that value - * is looked up in the VGA color registers. Then the color is displayed. - * This is done for compatability. However, the EGA registers are - * initialized by default to 0..5, 14, 7, 38..3F and not 0..F which means - * that unless these are reset, the VGA setpalette function will not - * update the correct palette register! - * - * DJGPP's GrSetColor() does _not_ set the EGA palette list, only the - * VGA color list. - * - * Note that the "traditional" method, using "int86(0x10)", is very slow - * when called in protected mode, so we use a faster method using video - * ports instead. - * - * On Watcom machines, we could simply use the special "_remapallpalette()" - * function, which not only sets both palette lists (see below) but also - * checks for legality of the monitor mode, but, if we are doing bitmapped - * graphics, that function forgets to set the EGA registers for some reason. - */ -static void activate_color_complex(void) -{ - int i; - printf("%c%c%c%c", 8, 8, 8, 8); - -#if 1 - - /* Edit the EGA palette */ - inportb(0x3da); - - /* Edit the colors */ - for (i = 0; i < 16; i++) - { - /* Set color "i" */ - outportb(0x3c0, i); - - /* To value "i" */ - outportb(0x3c0, i); - } - - /* Use that EGA palette */ - outportb(0x3c0, 0x20); - - /* Edit VGA palette, starting at color zero */ - outportb(0x3c8, 0); - - /* Send the colors */ - for (i = 0; i < 16; i++) - { - /* Send the red, green, blue components */ - outportb(0x3c9, ((ibm_color_complex[i]) & 0xFF)); - outportb(0x3c9, ((ibm_color_complex[i] >> 8) & 0xFF)); - outportb(0x3c9, ((ibm_color_complex[i] >> 16) & 0xFF)); - } - -#else /* 1 */ - - /* Set the colors */ - for (i = 0; i < 16; i++) - { - union REGS r; - - /* Set EGA color */ - r.h.ah = 0x10; - r.h.al = 0x00; - - /* Set color "i" */ - r.h.bl = i; - - /* To value "i" */ - r.h.bh = i; - - /* Do it */ - int86(0x10, &r, &r); - - /* Set VGA color */ - r.h.ah = 0x10; - r.h.al = 0x10; - - /* Set color "i" */ - r.h.bh = 0x00; - r.h.bl = i; - - /* Use this "green" value */ - r.h.ch = ((ibm_color_complex[i] >> 8) & 0xFF); - - /* Use this "blue" value */ - r.h.cl = ((ibm_color_complex[i] >> 16) & 0xFF); - - /* Use this "red" value */ - r.h.dh = ((ibm_color_complex[i]) & 0xFF); - - /* Do it */ - int86(0x10, &r, &r); - } - -#endif /* 1 */ - -} - - -#ifdef SUPPORT_GAMMA - -/* - * When set to TRUE, indicates that we can use gamma_table - */ -static bool gamma_table_ready = FALSE; - - -/* - * Build gamma correction table if requested and applicable - */ -static void setup_gamma_table(void) -{ - static u16b old_gamma_val = 0; - - /* (Re)build the table only when gamma value changes */ - if (gamma_val == old_gamma_val) return; - - /* Temporarily inactivate the table */ - gamma_table_ready = FALSE; - - /* Validate gamma_val */ - if ((gamma_val <= 0) || (gamma_val >= 256)) - { - /* Reset */ - old_gamma_val = gamma_val = 0; - - /* Leave it inactive */ - return; - } - - /* (Re)build the table */ - build_gamma_table(gamma_val); - - /* Remember gamma_val */ - old_gamma_val = gamma_val; - - /* Activate the table */ - gamma_table_ready = TRUE; -} - -#endif /* SUPPORT_GAMMA */ - - -/* - * Note the use of "(x >> 2)" to convert an 8 bit value to a 6 bit value - * without losing much precision. - */ -static int Term_xtra_ibm_react(void) -{ - int i; - - /* Complex method */ - if (use_color_complex) - { - long rv, gv, bv, code; - - bool change = FALSE; - -#ifdef SUPPORT_GAMMA - - /* Build gamma_table */ - setup_gamma_table(); - -#endif /* SUPPORT_GAMMA */ - - /* Save the default colors */ - for (i = 0; i < 16; i++) - { - /* Extract desired values */ - rv = angband_color_table[i][1]; - gv = angband_color_table[i][2]; - bv = angband_color_table[i][3]; - -#ifdef SUPPORT_GAMMA - - /* Hack - Gamma correction */ - if (gamma_table_ready) - { - rv = gamma_table[rv]; - gv = gamma_table[gv]; - bv = gamma_table[bv]; - } - -#endif /* SUPPORT_GAMMA */ - - /* 8 bit to 6 bit conversion */ - rv = rv >> 2; - gv = gv >> 2; - bv = bv >> 2; - - /* Extract a full color code */ - code = ((rv) | (gv << 8) | (bv << 16)); - - /* Activate changes */ - if (ibm_color_complex[i] != code) - { - /* Note the change */ - change = TRUE; - - /* Apply the desired color */ - ibm_color_complex[i] = code; - } - } - - /* Activate the palette if needed */ - if (change) activate_color_complex(); - } - - /* Simple method */ - else - { - /* Save the default colors */ - for (i = 0; i < 16; i++) - { - /* Simply accept the desired colors */ - ibm_color_simple[i] = angband_color_table[i][0]; - } - } - - /* Success */ - return (0); -} - - - -/* - * Hack -- set the cursor "visibility" - */ -static void curs_set(int v) -{ - /* If needed */ - if (saved_cur_v != v) - { - union REGS r; - - /* Set cursor */ - r.h.ah = 1; - - /* Visible */ - if (v) - { - /* Use the saved values */ - r.h.ch = saved_cur_high; - r.h.cl = saved_cur_low; - } - - /* Invisible */ - else - { - /* Make it invisible */ - r.h.ch = 0x20; - r.h.cl = 0x00; - } - - /* Make the call */ - int86(0x10, &r, &r); - - /* Save the cursor state */ - saved_cur_v = v; - } -} - - - -/* - * Process an event (check for a keypress) - * - * The keypress processing code is often the most system dependant part - * of Angband, since sometimes even the choice of compiler is important. - * - * For the IBM, we divide all keypresses into two categories, first, the - * "normal" keys, including all keys required to play Angband, and second, - * the "special" keys, such as keypad keys, function keys, and various keys - * used in combination with various modifier keys. - * - * To simplify this file, we use Angband's "macro processing" ability, in - * combination with a specialized "pref-ibm.prf" file, to handle most of the - * "special" keys, instead of attempting to fully analyze them here. This - * file only has to determine when a "special" key has been pressed, and - * translate it into a simple string which signals the use of a "special" - * key, the set of modifiers used, if any, and the hardware scan code of - * the actual key which was pressed. To simplify life for the user, we - * treat both "shift" keys as identical modifiers. - * - * The final encoding is "^_MMMxSS\r", where "MMM" encodes the modifiers - * ("C" for control, "S" for shift, "A" for alt, or any ordered combination), - * and "SS" encodes the keypress (as the two "digit" hexadecimal encoding of - * the scan code of the key that was pressed), and the "^_" and "x" and "\r" - * delimit the encoding for recognition by the macro processing code. - * - * Some important facts about scan codes follow. All "normal" keys use - * scan codes from 1-58. The "function" keys use 59-68 (and 133-134). - * The "keypad" keys use 69-83. Escape uses 1. Enter uses 28. Control - * uses 29. Left Shift uses 42. Right Shift uses 54. PrtScrn uses 55. - * Alt uses 56. Space uses 57. CapsLock uses 58. NumLock uses 69. - * ScrollLock uses 70. The "keypad" keys which use scan codes 71-83 - * are ordered KP7,KP8,KP9,KP-,KP4,KP5,KP6,KP+,KP1,KP2,KP3,INS,DEL. - * - * Using "bioskey(0x10)" instead of "bioskey(0)" apparently provides more - * information, including better access to the keypad keys in combination - * with various modifiers, but only works on "PC's after 6/1/86", and there - * is no way to determine if the function is provided on a machine. I have - * been told that without it you cannot detect, for example, control-left. - * The basic scan code + ascii value pairs returned by the keypad follow, - * with values in parentheses only available to "bioskey(0x10)". - * - * / * - + 1 2 3 4 - * Norm: 352f 372a 4a2d 4e2b 4f00 5000 5100 4b00 - * Shft: 352f 372a 4a2d 4e2b 4f31 5032 5133 4b34 - * Ctrl: (9500) (9600) (8e00) (9000) 7500 (9100) 7600 7300 - * - * 5 6 7 8 9 0 . Enter - * Norm: (4c00) 4d00 4700 4800 4900 5200 5300 (e00d) - * Shft: 4c35 4d36 4737 4838 4939 5230 532e (e00d) - * Ctrl: (8f00) 7400 7700 (8d00) 8400 (9200) (9300) (e00a) - * - * See "pref-ibm.prf" for the "standard" macros for various keys. - * - * Certain "bizarre" keypad keys (such as "enter") return a "scan code" - * of "0xE0", and a "usable" ascii value. These keys should be treated - * like the normal keys, see below. XXX XXX XXX Note that these "special" - * keys could be prefixed with an optional "ctrl-^" which would allow them - * to be used in macros without hurting their use in normal situations. - */ -static errr Term_xtra_ibm_event(int v) -{ - int i, k, s; - - bool mc = FALSE; - bool ms = FALSE; - bool ma = FALSE; - - - /* Hack -- Check for a keypress */ - if (!v && !bioskey(1)) return (1); - - /* Wait for a keypress */ - k = bioskey(0x10); - - /* Access the "modifiers" */ - i = bioskey(2); - - /* Extract the "scan code" */ - s = ((k >> 8) & 0xFF); - - /* Extract the "ascii value" */ - k = (k & 0xFF); - - /* Process "normal" keys */ - if ((s <= 58) || (s == 0xE0)) - { - /* Enqueue it */ - if (k) Term_keypress(k); - - /* Success */ - return (0); - } - - /* Extract the modifier flags */ - if (i & (1 << K_CTRL)) mc = TRUE; - if (i & (1 << K_LSHIFT)) ms = TRUE; - if (i & (1 << K_RSHIFT)) ms = TRUE; - if (i & (1 << K_ALT)) ma = TRUE; - - - /* Begin a "macro trigger" */ - Term_keypress(31); - - /* Hack -- Send the modifiers */ - if (mc) Term_keypress('C'); - if (ms) Term_keypress('S'); - if (ma) Term_keypress('A'); - - /* Introduce the hexidecimal scan code */ - Term_keypress('x'); - - /* Encode the hexidecimal scan code */ - Term_keypress(hexsym[s / 16]); - Term_keypress(hexsym[s % 16]); - - /* End the "macro trigger" */ - Term_keypress(13); - - /* Success */ - return (0); -} - - -/* - * Handle a "special request" - * - * The given parameters are "valid". - */ -static errr Term_xtra_ibm(int n, int v) -{ - int i; - - /* Analyze the request */ - switch (n) - { - /* Make a "bell" noise */ - case TERM_XTRA_NOISE: - { - /* Make a bell noise */ - (void)write(1, "\007", 1); - - /* Success */ - return (0); - } - - /* Set the cursor shape */ - case TERM_XTRA_SHAPE: - { - /* Set cursor shape */ - curs_set(v); - - /* Success */ - return (0); - } - - /* Flush one line of output */ - case TERM_XTRA_FROSH: - { - -#ifdef USE_VIRTUAL - -# ifdef USE_WAT - - /* Copy the virtual screen to the physical screen */ - memcpy(PhysicalScreen + (v*160), VirtualScreen + (v*160), 160); - -# else /* USE_WAT */ - - /* Apply the virtual screen to the physical screen */ - ScreenUpdateLine(VirtualScreen + ((v*cols) << 1), v); - -# endif /* USE_WAT */ - -#endif /* USE_VIRTUAL */ - - /* Success */ - return (0); - } - - /* Clear the screen */ - case TERM_XTRA_CLEAR: - { - -#ifdef USE_CONIO - - /* Clear the screen */ - clrscr(); - -#else /* USE_CONIO */ - - /* Clear each line (virtual or physical) */ - for (i = 0; i < rows; i++) - { - /* Clear the line */ - memcpy((VirtualScreen + ((i*cols) << 1)), wiper, (cols << 1)); - } - -# ifdef USE_VIRTUAL - -# ifdef USE_WAT - - /* Copy the virtual screen to the physical screen */ - memcpy(PhysicalScreen, VirtualScreen, 25*80*2); - -# else /* USE_WAT */ - - /* Erase the physical screen */ - ScreenClear(); - -# endif /* USE_WAT */ - -# endif /* USE_VIRTUAL */ - -#endif /* USE_CONIO */ - - /* Success */ - return (0); - } - - /* Process events */ - case TERM_XTRA_EVENT: - { - irc_poll(); - - /* Process one event */ - return (Term_xtra_ibm_event(v)); - } - - /* Flush events */ - case TERM_XTRA_FLUSH: - { - /* Strip events */ - while (!Term_xtra_ibm_event(FALSE)) /* loop */; - - /* Success */ - return (0); - } - - /* React to global changes */ - case TERM_XTRA_REACT: - { - /* React to "color_table" changes */ - return (Term_xtra_ibm_react()); - } - - /* Delay for some milliseconds */ - case TERM_XTRA_DELAY: - { - /* Delay if needed */ - if (v > 0) delay(v); - - /* Success */ - return (0); - } - - /* - * Scans for subdirectories in a directory "scansubdir_dir" - * and place teh result in "scansubdir_result/scansubdir_max" - */ - case TERM_XTRA_SCANSUBDIR: - { - struct ffblk f; - int done; - - done = findfirst(format("%s\\*", scansubdir_dir), &f, FA_DIREC); - - scansubdir_max = 0; - while ((!done) && (scansubdir_max < 255)) - { - if ((f.ff_attrib & FA_DIREC) && (strcmp(f.ff_name, ".")) && (strcmp(f.ff_name, ".."))) - { - string_free(scansubdir_result[scansubdir_max]); - scansubdir_result[scansubdir_max] = string_make(f.ff_name); - scansubdir_max++; - } - - done = findnext(&f); - } - - return 0; - } - } - - /* Unknown request */ - return (1); -} - - - -/* - * Move the cursor - * - * The given parameters are "valid". - */ -static errr Term_curs_ibm(int x, int y) -{ - -#ifdef USE_WAT - -# ifdef USE_CONIO - - /* Place the cursor */ - gotoxy(x + 1, y + 1); - -# else /* USE_CONIO */ - - union REGS r; - - r.h.ah = 2; - r.h.bh = 0; - r.h.dl = x; - r.h.dh = y; - - /* Place the cursor */ - int86(0x10, &r, &r); - -# endif /* USE_CONIO */ - -#else /* USE_WAT */ - - /* Move the cursor */ - ScreenSetCursor(y, x); - -#endif /* USE_WAT */ - - /* Success */ - return (0); -} - - -/* - * Erase a block of the screen - * - * The given parameters are "valid". - */ -static errr Term_wipe_ibm(int x, int y, int n) -{ - -#ifdef USE_CONIO - - /* Wipe the region */ - window(x + 1, y + 1, x + n, y + 1); - clrscr(); - window(1, 1, cols, rows); - -#else /* USE_CONIO */ - - /* Wipe part of the virtual (or physical) screen */ - memcpy(VirtualScreen + ((cols*y + x) << 1), wiper, n << 1); - -#endif /* USE_CONIO */ - - /* Success */ - return (0); -} - - -/* - * Place some text on the screen using an attribute - * - * The given parameters are "valid". Be careful with "a". - * - * The string "cp" has length "n" and is NOT null-terminated. - */ -static errr Term_text_ibm(int x, int y, int n, byte a, const char *cp) -{ - register int i; - register byte attr; - register byte *dest; - - - /* Handle "complex" color */ - if (use_color_complex) - { - /* Extract a color index */ - attr = (a & 0x0F); - } - - /* Handle "simple" color */ - else - { - /* Extract a color value */ - attr = ibm_color_simple[a & 0x0F]; - } - -#ifdef USE_CONIO - - /* Place the cursor */ - gotoxy(x + 1, y + 1); - - /* Set the attribute */ - textattr(attr); - - /* Dump the text */ - for (i = 0; i < n; i++) putch(cp[i]); - -#else /* USE_CONIO */ - - /* Access the virtual (or physical) screen */ - dest = VirtualScreen + (((cols * y) + x) << 1); - - /* Save the data */ - for (i = 0; i < n; i++) - { - /* Apply */ - *dest++ = cp[i]; - *dest++ = attr; - } - -#endif /* USE_CONIO */ - - /* Success */ - return (0); -} - - -/* - * Place some attr/char pairs on the screen - * - * The given parameters are "valid". - */ -#ifdef USE_TRANSPARENCY -static errr Term_pict_ibm(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp) -#else /* USE_TRANSPARENCY */ -static errr Term_pict_ibm(int x, int y, int n, const byte *ap, const char *cp) -#endif /* USE_TRANSPARENCY */ -{ - register int i; - register byte attr; - register byte *dest; - - -#ifdef USE_CONIO - - /* Place the cursor */ - gotoxy(x + 1, y + 1); - - /* Dump the text */ - for (i = 0; i < n; i++) - { - /* Handle "complex" color */ - if (use_color_complex) - { - /* Extract a color index */ - attr = (ap[i] & 0x0F); - } - - /* Handle "simple" color */ - else - { - /* Extract a color value */ - attr = ibm_color_simple[ap[i] & 0x0F]; - } - - /* Set the attribute */ - textattr(attr); - - /* Dump the char */ - putch(cp[i]); - } - -#else /* USE_CONIO */ - - /* Access the virtual (or physical) screen */ - dest = VirtualScreen + (((cols * y) + x) << 1); - - /* Save the data */ - for (i = 0; i < n; i++) - { - /* Handle "complex" color */ - if (use_color_complex) - { - /* Extract a color index */ - attr = (ap[i] & 0x0F); - } - - /* Handle "simple" color */ - else - { - /* Extract a color value */ - attr = ibm_color_simple[ap[i] & 0x0F]; - } - - /* Apply */ - *dest++ = cp[i]; - *dest++ = attr; - } - -#endif /* USE_CONIO */ - - /* Success */ - return (0); -} - - -/* - * Init a Term - */ -static void Term_init_ibm(term *t) -{ - /* XXX Nothing */ -} - - -/* - * Nuke a Term - */ -static void Term_nuke_ibm(term *t) -{ - -#ifdef USE_WAT - - /* Nothing */ - -#else /* USE_WAT */ - - union REGS r; - -#endif /* USE_WAT */ - - /* Move the cursor to the bottom of the screen */ - Term_curs_ibm(0, rows - 1); - -#ifdef USE_WAT - - /* Restore the original video mode */ - _setvideomode(_DEFAULTMODE); - -#else /* USE_WAT */ - - /* Restore the original video mode */ - r.h.ah = 0x00; - r.h.al = 0x03; - int86(0x10, &r, &r); - -#endif /* USE_WAT */ - - /* Make the cursor visible */ - curs_set(1); -} - - - -#ifdef USE_GRAPHICS - -#ifdef USE_286 - -/* - * In 286 mode we don't need to worry about translating from a 32bit - * pointer to a 16 bit pointer so we just call the interrupt function - * - * Note the use of "intr()" instead of "int86()" so we can pass - * segment registers. - */ -void enable_graphic_font(void *font) -{ - union REGPACK regs = - {0}; - - regs.h.ah = 0x11; /* Text font function */ - regs.h.bh = 0x10; /* Size of a character -- 16 bytes */ - regs.h.cl = 0xFF; /* Last character in font */ - regs.x.es = FP_SEG(font); /* Pointer to font */ - regs.x.bp = FP_OFF(font); - intr(0x10, ®s); -} - -#else /* USE_286 */ - -#ifdef USE_WAT - -/* -* This structure is used by the DMPI function to hold registers when -* doing a real mode interrupt call. (Stolen from the DJGPP <dpmi.h> - * header file). -*/ - -typedef union -{ - struct - { - unsigned long edi; - unsigned long esi; - unsigned long ebp; - unsigned long res; - unsigned long ebx; - unsigned long edx; - unsigned long ecx; - unsigned long eax; - } - d; - struct - { - unsigned short di, di_hi; - unsigned short si, si_hi; - unsigned short bp, bp_hi; - unsigned short res, res_hi; - unsigned short bx, bx_hi; - unsigned short dx, dx_hi; - unsigned short cx, cx_hi; - unsigned short ax, ax_hi; - unsigned short flags; - unsigned short es; - unsigned short ds; - unsigned short fs; - unsigned short gs; - unsigned short ip; - unsigned short cs; - unsigned short sp; - unsigned short ss; - } - x; - struct - { - unsigned char edi[4]; - unsigned char esi[4]; - unsigned char ebp[4]; - unsigned char res[4]; - unsigned char bl, bh, ebx_b2, ebx_b3; - unsigned char dl, dh, edx_b2, edx_b3; - unsigned char cl, ch, ecx_b2, ecx_b3; - unsigned char al, ah, eax_b2, eax_b3; - } - h; -} __dpmi_regs; - -unsigned __dpmi_allocate_dos_memory(int size, unsigned *selector) -{ - union REGPACK regs = - {0}; - - regs.w.ax = 0x100; /* DPMI function -- allocate low memory */ - regs.w.bx = size; /* Number of Paragraphs to allocate */ - intr(0x31, ®s); /* DPMI interface */ - - *selector = regs.w.dx; - return (regs.w.ax); -} - -void __dpmi_free_dos_memory(unsigned sel) -{ - union REGPACK regs = - {0}; - - regs.w.ax = 0x101; /* DPMI function -- free low memory */ - regs.x.edx = sel; /* PM selector for memory block */ - intr(0x31, ®s); /* DPMI interface */ -} - -void __dpmi_int(int intno, __dpmi_regs *dblock) -{ - union REGPACK regs = - {0}; - - regs.w.ax = 0x300; /* DPMI function -- real mode interrupt */ - regs.h.bl = intno; /* interrupt 0x10 */ - regs.x.edi = FP_OFF(dblock); /* Pointer to dblock (offset and segment) */ - regs.x.es = FP_SEG(dblock); - intr(0x31, ®s); /* DPMI interface */ -} - -unsigned short __dpmi_sel = 0x0000; -#define _farsetsel(x) __dpmi_sel=(x) -extern void _farnspokeb(unsigned long offset, unsigned char value); -#pragma aux _farnspokeb = \ -"push fs" \ -"mov fs,__dpmi_sel" \ -"mov fs:[eax],bl" \ -"pop fs" \ -parm [eax] [bl]; - -#else /* USE_WAT */ - -#include <dpmi.h> -#include <go32.h> -#include <sys/farptr.h> - -#endif /* USE_WAT */ - - -/* -* Since you cannot send 32bit pointers to a 16bit interrupt handler -* and the video BIOS wants a (16bit) pointer to the font, we have -* to allocate a block of dos memory, copy the font into it, then -* translate a 32bit pointer into a 16bit pointer to that block. -* -* DPMI - Dos Protected Mode Interface provides functions that let -* us do that. -*/ -void enable_graphic_font(const char *font) -{ - __dpmi_regs dblock = {{0}}; - - unsigned seg, sel, i; - - /* - * Allocate a block of memory 4096 bytes big in `low memory' so a real - * mode interrupt can access it. Real mode pointer is returned as seg:0 - * Protected mode pointer is sel:0. - */ - seg = __dpmi_allocate_dos_memory(256, &sel); - - /* Copy the information into low memory buffer, by copying one byte at - * a time. According to the info in <sys/farptr.h>, the functions - * _farsetsel() and _farnspokeb() will optimise away completely - */ - _farsetsel(sel); /* Set the selector to write to */ - for (i = 0; i < 4096; i++) - { - _farnspokeb(i, *font++); /* Copy 1 byte into low (far) memory */ - } - - /* - * Now we use DPMI as a jumper to call the real mode interrupt. This - * is needed because loading `es' while in protected mode with a real - * mode pointer will cause an Protection Fault and calling the interrupt - * directly using the protected mode pointer will result in garbage - * being received by the interrupt routine - */ - dblock.d.eax = 0x1100; /* BIOS function -- set font */ - dblock.d.ebx = 0x1000; /* bh = size of a letter; bl = 0 (reserved) */ - dblock.d.ecx = 0x00FF; /* Last character in font */ - dblock.x.es = seg; /* Pointer to font segment */ - dblock.d.ebp = 0x0000; /* Pointer to font offset */ - - __dpmi_int(0x10, &dblock); - - /* We're done with the low memory, free it */ - __dpmi_free_dos_memory(sel); -} - -#endif /* USE_286 */ - -#endif /* ALLOW_GRAPH */ - -#ifdef USE_DOSSOCK -void *zsock_connect(char *hos, short port) -{ - struct hostent *host; - struct sockaddr_in sin; - int *client; - - MAKE(client, int); - *client = socket(AF_INET, SOCK_STREAM, 0); - - host = gethostbyname(hos); - - memset(&sin, 0, sizeof sin); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = ((struct in_addr *)(host->h_addr))->s_addr; - sin.sin_port = htons(port); - - if (connect(*client, (struct sockaddr*)&sin, sizeof sin) == -1) - { - /* could not connect to server */ - return NULL; - } - - return client; -} - -bool zsock_can_read(void *client) -{ - struct timeval t; - fd_set rd; - int *c = client; - - FD_ZERO(&rd); - FD_SET(*c, &rd); - t.tv_sec = 0; - t.tv_usec = 0; - select(*c + 1, &rd, NULL, NULL, &t); - if (FD_ISSET(*c, &rd)) return TRUE; - else return (FALSE); -} - -bool zsock_wait(void *client) -{ - struct timeval t; - fd_set rd; - int *c = client; - - t.tv_sec = 30; - t.tv_usec = 0; - - FD_ZERO(&rd); - FD_SET(*c, &rd); - select(*c + 1, &rd, NULL, NULL, &t); - if (FD_ISSET(*c, &rd)) return TRUE; - else return (FALSE); -} - -void zsock_disconnect(void *client) -{ - close(*(int*)client); - FREE(client, int); -} - -void zsock_send(void *sock, char *str) -{ - send(*(int*)sock, str, strlen(str), 0); -} - -void zsock_recv(void *sock, char *str, int len) -{ - char c; - int l = 0; - - while ((l < len) && zsock_can_read(sock)) - { - if (!recv(*(int*)sock, &c, 1, 0)) - { - irc_disconnect(); - break; - } - if (c == '\r') continue; - if (c == '\n') break; - str[l++] = c; - } - str[l] = '\0'; -} -#endif - - -/* - * Initialize the IBM "visual module" - * - * Hack -- we assume that "blank space" should be "white space" - * (and not "black space" which might make more sense). - * - * Note the use of "((x << 2) | (x >> 4))" to "expand" a 6 bit value - * into an 8 bit value, without losing much precision, by using the 2 - * most significant bits as the least significant bits in the new value. - */ -errr init_ibm(void) -{ - int i; - int mode; - - term *t = &term_screen_body; - - union REGS r; - - /* Check for "Windows" */ - if (getenv("windir")) - { - r.h.ah = 0x16; /* Windows API Call -- Set device focus */ - r.h.al = 0x8B; /* Causes Dos boxes to become fullscreen */ - r.h.bh = r.h.bl = 0x00; /* 0x0000 = current Dos box */ - int86(0x2F, &r, &r); /* Call the Windows API */ - } - - /* Initialize "color_table" */ - for (i = 0; i < 16; i++) - { - long rv, gv, bv; - - /* Extract desired values */ - rv = angband_color_table[i][1] >> 2; - gv = angband_color_table[i][2] >> 2; - bv = angband_color_table[i][3] >> 2; - - /* Extract the "complex" codes */ - ibm_color_complex[i] = ((rv) | (gv << 8) | (bv << 16)); - - /* Save the "simple" codes */ - angband_color_table[i][0] = ibm_color_simple[i]; - } - -#ifdef USE_WAT - - /* Set the video mode */ - if (_setvideomode(_VRES16COLOR)) - { - mode = 0x13; - } - - /* Wimpy monitor */ - else - { - mode = 0x03; - } - - /* Force 25 line mode */ - _setvideomode(_TEXTC80); - _settextrows(25); - -#else /* USE_WAT */ - - /* Set video mode */ - r.h.ah = 0x00; - r.h.al = 0x13; /* VGA only mode */ - int86(0x10, &r, &r); - - /* Get video mode */ - r.h.ah = 0x0F; - int86(0x10, &r, &r); - mode = r.h.al; - - /* Set video mode */ - r.h.ah = 0x00; - r.h.al = 0x03; /* Color text mode */ - int86(0x10, &r, &r); - -#endif /* USE_WAT */ - - /* Check video mode */ - if (mode == 0x13) - { - /* Remember the mode */ - use_color_complex = TRUE; - - /* Instantiate the color set */ - activate_color_complex(); - } - -#ifdef USE_GRAPHICS - - /* Try to activate bitmap graphics */ - if (arg_graphics && use_color_complex) - { - FILE *f; - - char buf[4096]; - - /* Build the filename */ - path_build(buf, 1024, ANGBAND_DIR_XTRA, "angband.fnt"); - - /* Open the file */ - f = fopen(buf, "rb"); - - /* Okay */ - if (f) - { - /* Load the bitmap data */ - if (fread(buf, 1, 4096, f) != 4096) - { - quit("Corrupt 'angband.fnt' file"); - } - - /* Close the file */ - fclose(f); - - /* Enable graphics */ - enable_graphic_font(buf); - - /* Enable colors (again) */ - activate_color_complex(); - - /* Use graphics */ - use_graphics = TRUE; - } - } - -#endif - -#ifdef USE_CONIO -#else /* USE_CONIO */ - - /* Build a "wiper line" */ - for (i = 0; i < 80; i++) - { - /* Space */ - wiper[2*i] = ' '; - - /* Black */ - wiper[2*i + 1] = TERM_WHITE; - } - -#endif /* USE_CONIO */ - - -#ifdef USE_VIRTUAL - - /* Make the virtual screen */ - C_MAKE(VirtualScreen, rows * cols * 2, byte); - -#endif /* USE_VIRTUAL */ - - - /* Erase the screen */ - Term_xtra_ibm(TERM_XTRA_CLEAR, 0); - - - /* Place the cursor */ - Term_curs_ibm(0, 0); - - - /* Access the "default" cursor info */ - r.h.ah = 3; - r.h.bh = 0; - - /* Make the call */ - int86(0x10, &r, &r); - - /* Extract the standard cursor info */ - saved_cur_v = 1; - saved_cur_high = r.h.ch; - saved_cur_low = r.h.cl; - - - /* Initialize the term */ - term_init(t, 80, 24, 256); - -#ifdef USE_CONIO -#else /* USE_CONIO */ - - /* Always use "Term_pict()" */ - t->always_pict = TRUE; - -#endif /* USE_CONIO */ - - /* Use "white space" to erase */ - t->attr_blank = TERM_WHITE; - t->char_blank = ' '; - - /* Prepare the init/nuke hooks */ - t->init_hook = Term_init_ibm; - t->nuke_hook = Term_nuke_ibm; - - /* Connect the hooks */ - t->xtra_hook = Term_xtra_ibm; - t->curs_hook = Term_curs_ibm; - t->wipe_hook = Term_wipe_ibm; - t->text_hook = Term_text_ibm; - t->pict_hook = Term_pict_ibm; - - /* Save it */ - term_screen = t; - - /* Activate it */ - Term_activate(term_screen); - - /* Success */ - return 0; -} - - -#endif /* USE_IBM */ |