summaryrefslogtreecommitdiff
path: root/src/main-ibm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main-ibm.c')
-rw-r--r--src/main-ibm.c1594
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, &regs);
-}
-
-#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, &regs); /* 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, &regs); /* 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, &regs); /* 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 */