OSDN Git Service

shrink mine
[nethackexpress/trunk.git] / sys / msdos / vidvga.c
1 /*   SCCS Id: @(#)vidvga.c   3.4     1996/02/16                   */
2 /*   Copyright (c) NetHack PC Development Team 1995                 */
3 /*   NetHack may be freely redistributed.  See license for details. */
4 /*
5  * vidvga.c - VGA Hardware video support
6  */
7
8 #include "hack.h"
9
10 #ifdef SCREEN_VGA               /* this file is for SCREEN_VGA only    */
11 #include "pcvideo.h"
12 #include "tile.h"
13 #include "pctiles.h"
14
15 #include <dos.h>
16 #include <ctype.h>
17 #include "wintty.h"
18
19 # ifdef __GO32__
20 #include <pc.h>
21 #include <unistd.h>
22 # endif
23
24 /*=========================================================================
25  * VGA Video supporting routines (for tiles).
26  *
27  * The following routines carry out the lower level video functions required
28  * to make PC NetHack work with VGA graphics.
29  *
30  *   - The binary files NetHack1.tib and NetHacko.tib must be in your
31  *     game directory.  Currently, unpredictable results may occur if they 
32  *     aren't since the code hasn't been tested with it missing (yet).
33  *
34  * Notes (96/02/16):
35  *
36  *   - Cursor emulation on the map is now implemented.  The input routine
37  *     in msdos.c calls the routine to display the cursor just before
38  *     waiting for input, and hides the cursor immediately after satisfying 
39  *     the input request.
40  *
41  *   - A check for a VGA adapter is implemented.
42  *
43  *   - With 640 x 480 resolution, the use of 16 x 16 icons allows only 40
44  *     columns for the map display.  This makes it necessary to support the
45  *     TTY CLIPPING code.  The right/left scrolling with this can be
46  *     a little annoying.  Feel free to rework the routines.
47  *
48  *   - NetHack1.tib is built from text files derived from bitmap files 
49  *     provided by Warwick Allison, using routines developed and supplied 
50  *     by Janet Walz.  The icons are very well done and thanks to 
51  *     Warwick Allison for an excellent effort!
52  *
53  *   - The text fonts that this is using while in graphics mode come from
54  *     the Video BIOS ROM on board the VGA adapter.  Code in vga_WriteChar
55  *     copies the appropriate pixels from the video ROM to the Video buffer.
56  *
57  *   - Currently, most of the routines are in an ifdef OVLB.
58  *     If you change that, you may have to muck with some of the 
59  *     variable declarations which now assume this.  This is not a 
60  *     problem in a non-overlaid environment (djgpp for example).
61  *
62  *   - VGA 640 by 480, 16 colour mode (0x12) uses an odd method to 
63  *     represent a colour value from the palette. There are four 
64  *     planes of video memory, all overlaid at the same memory location.
65  *     For example, if a pixel has the colour value 7:
66  *
67  *           0 1 1 1
68  *            \ \ \ \
69  *             \ \ \ plane 0 
70  *              \ \ plane 1
71  *               \ plane 2
72  *                plane 3
73  *
74  *   - VGA write mode 2 requires that a read be done before a write to
75  *     set some latches on the card.  The value read had to be placed
76  *     into a variable declared 'volatile' to prevent djgpp from
77  *     optimizing away the entire instruction (the value was assigned
78  *     to a variable which was never used).  This corrects the striping
79  *     problem that was apparent with djgpp.
80  *
81  *   - A check for valid mode switches has been added.
82  *
83  *   - No tiles are displayed on the Rogue Level in keeping with the
84  *     original Rogue.  The display adapter remains in graphics mode 
85  *     however.
86  *
87  *   - Added handling for missing NetHackX.tib files, and resort to using
88  *     video:default and tty if one of them can't be located.
89  *
90  * ToDo (96/02/17):
91  *
92  *   - Nothing prior to release.
93  *=========================================================================
94  */
95
96
97 # if defined(_MSC_VER)
98 #  if _MSC_VER >= 700
99 #pragma warning(disable:4018)   /* signed/unsigned mismatch */
100 #pragma warning(disable:4127)   /* conditional expression is constant */
101 #pragma warning(disable:4131)   /* old style declarator */
102 #pragma warning(disable:4305)   /* prevents complaints with MK_FP */
103 #pragma warning(disable:4309)   /* initializing */
104 #    if _MSC_VER > 700
105 #pragma warning(disable:4759)   /* prevents complaints with MK_FP */
106 #    endif
107 #  endif
108 # include <conio.h>
109 # endif
110
111 /* STATIC_DCL void FDECL(vga_NoBorder, (int));  */
112 void FDECL(vga_gotoloc, (int,int));  /* This should be made a macro */
113 void NDECL(vga_backsp);
114 #ifdef SCROLLMAP
115 STATIC_DCL void FDECL(vga_scrollmap,(BOOLEAN_P));
116 #endif
117 STATIC_DCL void FDECL(vga_redrawmap,(BOOLEAN_P));
118 void FDECL(vga_cliparound,(int, int));
119 STATIC_OVL void FDECL(decal_planar,(struct planar_cell_struct *, unsigned));
120
121 #ifdef POSITIONBAR
122 STATIC_DCL void NDECL(positionbar);
123 static void FDECL(vga_special,(int, int, int));
124 #endif
125
126 extern int clipx, clipxmax;     /* current clipping column from wintty.c */
127 extern boolean clipping;        /* clipping on? from wintty.c */
128 extern int savevmode;           /* store the original video mode */
129 extern int curcol,currow;       /* current column and row        */
130 extern int g_attribute;
131 extern int attrib_text_normal;  /* text mode normal attribute */
132 extern int attrib_gr_normal;    /* graphics mode normal attribute */
133 extern int attrib_text_intense; /* text mode intense attribute */
134 extern int attrib_gr_intense;   /* graphics mode intense attribute */
135 extern boolean inmap;           /* in the map window */
136
137 /*
138  * Global Variables
139  */ 
140
141 STATIC_VAR unsigned char __far *font;
142 STATIC_VAR char *screentable[SCREENHEIGHT];
143
144 STATIC_VAR char *paletteptr;
145 STATIC_VAR struct map_struct {
146         int glyph;
147         int ch;
148         int attr;
149         unsigned special;
150 }  map[ROWNO][COLNO];   /* track the glyphs */
151
152 # define vga_clearmap() { int x,y; for (y=0; y < ROWNO; ++y) \
153         for (x=0; x < COLNO; ++x) { map[y][x].glyph = cmap_to_glyph(S_stone); \
154         map[y][x].ch = S_stone; map[y][x].attr = 0; map[y][x].special = 0;} }
155 # define TOP_MAP_ROW 1
156 #  if defined(OVLB)
157 STATIC_VAR int vgacmap[CLR_MAX] = {0,3,5,9,4,8,12,14,11,2,6,7,1,8,12,13};
158 STATIC_VAR int viewport_size = 40;
159 /* STATIC_VAR char masktable[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; */
160 /* STATIC_VAR char bittable[8]= {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; */
161 #if 0
162 STATIC_VAR char defpalette[] = {        /* Default VGA palette         */
163         0x00, 0x00, 0x00,
164         0x00, 0x00, 0xaa,
165         0x00, 0xaa, 0x00,
166         0x00, 0xaa, 0xaa,
167         0xaa, 0x00, 0x00,
168         0xaa, 0x00, 0xaa,
169         0xaa, 0xaa, 0x00,
170         0xaa, 0xaa, 0xaa,
171         0x55, 0x55, 0x55,
172         0xcc, 0xcc, 0xcc,
173         0x00, 0x00, 0xff,
174         0x00, 0xff, 0x00,
175         0xff, 0x00, 0x00,
176         0xff, 0xff, 0x00,
177         0xff, 0x00, 0xff,
178         0xff, 0xff, 0xff
179         };
180 #endif
181
182 #   ifndef ALTERNATE_VIDEO_METHOD
183 int vp[SCREENPLANES] = {8,4,2,1};
184 #   endif
185 int vp2[SCREENPLANES] = {1,2,4,8};
186 #  else
187 extern int vgacmap[CLR_MAX];
188 extern int viewport_size;
189 extern char masktable[8];
190 extern char bittable[8];
191 extern char defpalette[];
192 #   ifndef ALTERNATE_VIDEO_METHOD
193 extern int vp[SCREENPLANES];
194 #   endif
195 extern int vp2[SCREENPLANES];
196 #  endif /* OVLB */
197
198 STATIC_VAR struct planar_cell_struct *planecell;
199 STATIC_VAR struct overview_planar_cell_struct *planecell_O;
200
201 # if defined(USE_TILES)
202 STATIC_VAR struct tibhdr_struct tibheader;
203 /* extern FILE *tilefile; */ /* Not needed in here most likely */
204 # endif
205
206 /* STATIC_VAR int  g_attribute; */      /* Current attribute to use */
207
208 #ifdef OVLB
209 void
210 vga_get_scr_size()
211 {
212         CO = 80;
213         LI = 29;
214 }
215 #endif /*OVLB*/
216
217
218
219 # ifdef OVLB
220
221 void
222 vga_backsp()
223 {
224         int col,row;
225
226         col = curcol;           /* Character cell row and column */
227         row = currow;
228
229         if (col > 0) col = col-1;
230         vga_gotoloc(col,row);
231 }
232
233 # endif /* OVLB */
234 # ifdef OVL0
235
236 void
237 vga_clear_screen(colour)
238 int colour;
239 {
240         char __far *pch;
241         int y,j;
242         char volatile a;
243
244         outportb(0x3ce,5);
245         outportb(0x3cf,2);
246
247         for (y=0; y < SCREENHEIGHT; ++y) {
248                 pch = screentable[y];
249                 for (j=0; j < SCREENBYTES; ++j) {
250                         outportb(0x3ce,8);
251                         outportb(0x3cf,255);
252                         a = READ_ABSOLUTE(pch); /* Must read , then write */
253                         WRITE_ABSOLUTE(pch, (char)colour);
254                         ++pch;
255                 }
256         }
257         outportb(0x3ce,5);
258         outportb(0x3cf,0);
259         if (iflags.tile_view) vga_clearmap();
260         vga_gotoloc(0,0);       /* is this needed? */
261 }
262
263 void
264 vga_cl_end(col,row)     /* clear to end of line */
265 int col,row;
266 {
267         int count;
268
269         /*
270          * This is being done via character writes.
271          * This should perhaps be optimized for speed by using VGA write
272          * mode 2 methods as did clear_screen()
273          */
274         for (count = col; count < (CO-1); ++count) {
275                 vga_WriteChar(' ',count,row,BACKGROUND_VGA_COLOR);
276         }
277 }
278
279 void
280 vga_cl_eos(cy)  /* clear to end of screen */
281 int cy;
282 {
283         int count;
284
285         cl_end();
286         while(cy <= LI-2) {
287                 for (count = 0; count < (CO-1); ++count) {
288                         vga_WriteChar(' ',count,cy,
289                                 BACKGROUND_VGA_COLOR);
290                 }
291                 cy++;
292         }
293 }
294
295
296 # endif /* OVL0 */
297
298 # ifdef OVLB
299 void
300 vga_tty_end_screen()
301 {
302         vga_clear_screen(BACKGROUND_VGA_COLOR);
303         vga_SwitchMode(MODETEXT);
304 }
305
306
307 void
308 vga_tty_startup(wid, hgt)
309     int *wid, *hgt;
310 {
311
312         /* code to sense display adapter is required here - MJA */
313
314         vga_get_scr_size();
315         if (CO && LI) {
316                 *wid = CO;
317                 *hgt = LI;
318         }
319
320         attrib_gr_normal    = ATTRIB_VGA_NORMAL;
321         attrib_gr_intense   = ATTRIB_VGA_INTENSE;
322         g_attribute         = attrib_gr_normal; /* Give it a starting value */
323 }
324 # endif /* OVLB */
325
326 /*
327  * Screen output routines (these are heavily used).
328  *
329  * These are the 3 routines used to place information on the screen
330  * in the VGA PC tty port of NetHack.  These are the routines
331  * that get called by the general interface routines in video.c.
332  *
333  * vga_xputs -Writes a c null terminated string at the current location.
334  *
335  * vga_xputc -Writes a single character at the current location. Since
336  *            various places in the code assume that control characters
337  *            can be used to control, we are forced to interpret some of
338  *            the more common ones, in order to keep things looking correct.
339  *
340  * vga_xputg -This routine is used to display a graphical representation of a
341  *            NetHack glyph (a tile) at the current location.  For more
342  *            information on NetHack glyphs refer to the comments in
343  *            include/display.h.
344  *
345  */
346
347 # ifdef OVL0
348 void
349 vga_xputs(s,col,row)
350 const char *s;
351 int col,row;
352 {
353
354         if (s != (char *)0) {
355                 vga_WriteStr((char *)s,strlen(s),col,row,g_attribute);
356         }
357 }
358
359 void
360 vga_xputc(ch,attr)      /* write out character (and attribute) */
361 char ch;
362 int attr;
363 {
364         int col,row;
365
366         col = curcol;
367         row = currow;
368
369         switch(ch) {
370             case '\n':  
371                         col = 0;
372                         ++row;
373                         break;
374             default:
375                         vga_WriteChar((unsigned char)ch,col,row,attr);
376                         if (col < (CO -1 )) ++col;
377                         break;
378         } /* end switch */
379         vga_gotoloc(col,row);
380 }
381
382 #  if defined(USE_TILES)
383 void
384 vga_xputg(glyphnum,ch, special) /* Place tile represent. a glyph at current location */
385 int glyphnum;
386 int ch;
387 unsigned special;       /* special feature: corpse, invis, detected, pet, ridden - hack.h */
388 {
389         int col,row;
390         int attr;
391         int ry;
392
393         row = currow;
394         col = curcol;
395         if ((col < 0 || col >= COLNO) ||
396             (row < TOP_MAP_ROW || row >= (ROWNO + TOP_MAP_ROW))) return;
397         ry = row - TOP_MAP_ROW;
398         map[ry][col].glyph = glyphnum;
399         map[ry][col].ch = ch;
400         map[ry][col].special = special;
401         attr = (g_attribute == 0) ? attrib_gr_normal : g_attribute;
402         map[ry][col].attr = attr;
403         if (iflags.traditional_view) {
404             vga_WriteChar((unsigned char)ch,col,row,attr);
405         } else if (!iflags.over_view) {
406             if ((col >= clipx) && (col <= clipxmax)) {
407                 if (!ReadPlanarTileFile(glyph2tile[glyphnum], &planecell)) {
408                         if (map[ry][col].special) decal_planar(planecell, special);
409                         vga_DisplayCell(planecell, 
410                                         col - clipx, row);
411                 } else
412                         pline("vga_xputg: Error reading tile (%d,%d) from file",
413                                         glyphnum,glyph2tile[glyphnum]);
414             }
415         } else {
416             if (!ReadPlanarTileFile_O(glyph2tile[glyphnum], &planecell_O))
417                         vga_DisplayCell_O(planecell_O, col, row);
418             else
419                         pline("vga_xputg: Error reading tile (%d,%d) from file",
420                                         glyphnum,glyph2tile[glyphnum]);
421         }
422         if (col < (CO - 1 )) ++col;
423         vga_gotoloc(col,row);
424 }
425 #  endif /* USE_TILES */
426
427 /*
428  * Cursor location manipulation, and location information fetching
429  * routines.
430  * These include:
431  *
432  * vga_gotoloc(x,y)     - Moves the "cursor" on screen to the specified x
433  *                       and y character cell location.  This routine
434  *                       determines the location where screen writes
435  *                       will occur next, it does not change the location
436  *                       of the player on the NetHack level.
437  */
438  
439 void
440 vga_gotoloc(col,row)
441 int col,row;
442 {
443         curcol = min(col,CO - 1); /* protection from callers */
444         currow = min(row,LI - 1);
445 }
446
447 #  if defined(USE_TILES) && defined(CLIPPING)
448 void
449 vga_cliparound(x, y)
450 int x, y;
451 {
452         extern boolean restoring;
453         int oldx = clipx;
454
455         if (!iflags.tile_view || iflags.over_view || iflags.traditional_view)
456                 return;
457
458         if (x < clipx + 5) {
459                 clipx = max(0, x - (viewport_size / 2));
460                 clipxmax = clipx + (viewport_size - 1);
461         }
462         else if (x > clipxmax - 5) {
463                 clipxmax = min(COLNO - 1, x + (viewport_size / 2));
464                 clipx = clipxmax - (viewport_size - 1);
465         }
466         if (clipx != oldx) {
467             if (on_level(&u.uz0, &u.uz) && !restoring)
468                 /* (void) doredraw(); */
469                 vga_redrawmap(1);
470         }
471 }
472
473 STATIC_OVL void
474 vga_redrawmap(clearfirst)
475 boolean clearfirst;
476 {
477         int j,x,y,t;
478         char __far *pch;
479         char volatile a;
480         
481         if (clearfirst) {
482                 /* y here is in pixel rows */
483                 outportb(0x3ce,5);
484                 outportb(0x3cf,2);
485                 t = TOP_MAP_ROW * ROWS_PER_CELL;
486                 for (y = t; y < (ROWNO * ROWS_PER_CELL) + t; ++y) {
487                         pch = screentable[y];
488                         for (j=0; j < SCREENBYTES; ++j) {
489                                 outportb(0x3ce,8);
490                                 outportb(0x3cf,255);
491                                  /* On VGA mode2, must read first, then write */
492                                 a = READ_ABSOLUTE(pch);
493                                 WRITE_ABSOLUTE(pch, (char)BACKGROUND_VGA_COLOR);
494                                 ++pch;
495                         }
496                 }
497                 outportb(0x3ce,5);
498                 outportb(0x3cf,0);
499         }
500         /* y here is in screen rows*/
501 #    ifdef ROW_BY_ROW
502         for (y = 0; y < ROWNO; ++y)
503                 for (x = clipx; x <= clipxmax; ++x) {
504 #    else
505         for (x = clipx; x <= clipxmax; ++x)
506                 for (y = 0; y < ROWNO; ++y) {
507 #    endif
508                     if (iflags.traditional_view) {
509                         if (!(clearfirst && map[y][x].ch == S_stone))
510                                 vga_WriteChar(
511                                         (unsigned char)map[y][x].ch,
512                                         x,y + TOP_MAP_ROW,map[y][x].attr);
513                     } else {
514                       t = map[y][x].glyph;
515                       if (!(clearfirst && t == cmap_to_glyph(S_stone))) {
516                         if (!iflags.over_view) {
517                                 if (!ReadPlanarTileFile(glyph2tile[t], 
518                                     &planecell)) {
519                                         if (map[y][x].special)
520                                                 decal_planar(planecell, map[y][x].special);
521                                         vga_DisplayCell(planecell,
522                                                 x - clipx, y + TOP_MAP_ROW);
523                                 } else
524                               pline("vga_redrawmap: Error reading tile (%d,%d)",
525                                          t,glyph2tile[t]);
526                         } else {
527                                 if (!ReadPlanarTileFile_O(glyph2tile[t], 
528                                      &planecell_O)) {
529                                         vga_DisplayCell_O(planecell_O,
530                                                 x, y + TOP_MAP_ROW);
531                                 } else
532                              pline("vga_redrawmap: Error reading tile (%d,%d)",
533                                         t,glyph2tile[t]);
534                         }
535                       }
536                     }
537                 }
538 }
539 #  endif /* USE_TILES && CLIPPING */
540 # endif /* OVL0 */
541 # ifdef OVL2
542
543 void
544 vga_userpan(left)
545 boolean left;
546 {
547         int x;
548
549 /*      pline("Into userpan"); */
550         if (iflags.over_view || iflags.traditional_view) return;
551         if (left)
552                 x = min(COLNO - 1, clipxmax + 10);
553         else 
554                 x = max(0, clipx - 10);
555         vga_cliparound(x, 10);  /* y value is irrelevant on VGA clipping */
556         positionbar();
557         vga_DrawCursor();
558 }
559
560
561 void vga_overview(on)
562 boolean on;
563 {
564 /*      vga_HideCursor(); */
565         if (on) {
566                 iflags.over_view = TRUE;
567                 clipx = 0;
568                 clipxmax = CO - 1;
569         } else {
570                 iflags.over_view = FALSE;
571                 clipx = max(0, (curcol - viewport_size / 2));
572                 if (clipx > ((CO - 1) - viewport_size)) 
573                         clipx = (CO - 1) - viewport_size;
574                 clipxmax = clipx + (viewport_size - 1);
575         }
576 }
577
578 void vga_traditional(on)
579 boolean on;
580 {
581 /*      vga_HideCursor(); */
582         if (on) {
583 /*              switch_graphics(ASCII_GRAPHICS); */
584                 iflags.traditional_view = TRUE;
585                 clipx = 0;
586                 clipxmax = CO - 1;
587         } else {
588                 iflags.traditional_view = FALSE;
589                 if (!iflags.over_view) {
590                         clipx = max(0, (curcol - viewport_size / 2));
591                         if (clipx > ((CO - 1) - viewport_size)) 
592                                 clipx = (CO - 1) - viewport_size;
593                         clipxmax = clipx + (viewport_size - 1);
594                 }
595         }
596 }
597
598 void vga_refresh()
599 {
600         positionbar();
601         vga_redrawmap(1);
602         vga_DrawCursor();
603 }
604
605 #  ifdef SCROLLMAP
606 STATIC_OVL void
607 vga_scrollmap(left)
608 boolean left;
609 {
610         int j,x,y,t;
611         int i,pixx,pixy,x1,y1,x2,y2;
612         int byteoffset, vplane;
613         char __far *tmp1;
614         char __far *tmp2;
615         unsigned char source[SCREENPLANES][80];
616         unsigned char first,second;
617
618         
619         pixy = row2y(TOP_MAP_ROW);                /* convert to pixels */
620         pixx = col2x(x1);
621         if (left) {
622                 x1 = 20;
623                 x2 = 0;
624         } else {
625                 x1 = 0;
626                 x2 = 20;
627         }
628         /* read each row, all columns but the one to be replaced */
629         for(i = 0;i < (ROWNO-1) * ROWS_PER_CELL; ++i) {
630             tmp1 = screentable[i + pixy];
631             tmp1 += x1;
632             for(vplane=0; vplane < SCREENPLANES; ++vplane) {
633                 egareadplane(vplane);
634                 for (byteoffset = 0; byteoffset < 20; ++byteoffset) {
635                         tmp2 = tmp1 + byteoffset;
636                         source[vplane][byteoffset] = READ_ABSOLUTE(tmp2);
637                 }
638             }
639             tmp1 = screentable[i + pixy];
640             tmp1 += x2;
641             for(vplane=0; vplane < SCREENPLANES; ++vplane) {
642                 egawriteplane(vp2[vplane]);
643                 for (byteoffset = 0; byteoffset < 20; ++byteoffset) {
644                         tmp2 = tmp1 + byteoffset;
645                         WRITE_ABSOLUTE(tmp2,source[vplane][byteoffset]);
646                 }
647             }
648             egawriteplane(15);
649         }
650
651         if (left) {
652                 i = clipxmax - 1;
653                 j = clipxmax;
654         } else {
655                 i = clipx;
656                 j = clipx + 1;
657         }
658         for (y = 0; y < ROWNO; ++y) {
659             for (x = i; x < j; x += 2) {
660                 t = map[y][x].glyph;
661                 if (!ReadPlanarTileFile(glyph2tile[t], &planecell))
662                         if (map[y][x].special) decal_planar(planecell, map[y][x].special);
663                         vga_DisplayCell(planecell, x - clipx, y + TOP_MAP_ROW);
664                 else
665                         pline("vga_shiftmap: Error reading tile (%d,%d)",
666                                 t, glyph2tile[t]);              
667             }
668         }
669 }
670 #   endif /* SCROLLMAP */
671 # endif /* OVL2 */
672
673 # ifdef OVLB
674 STATIC_OVL void
675 decal_planar(gp, special)
676 struct planar_cell_struct *gp;
677 unsigned special;
678 {
679     if (special & MG_CORPSE) {
680     } else if (special & MG_INVIS)  {
681     } else if (special & MG_DETECT) {
682     } else if (special & MG_PET)    {
683     } else if (special & MG_RIDDEN) {
684     }
685 }
686
687 /*
688  * Open tile files,
689  * initialize the SCREEN, switch it to graphics mode,
690  * initialize the pointers to the fonts, clear
691  * the screen.
692  *
693  */
694 void vga_Init(void)
695 {
696      int i;
697
698 #   ifdef USE_TILES
699      int tilefailure = 0;
700 /*
701  * Attempt to open the required tile files. If we can't
702  * don't perform the video mode switch, use TTY code instead.
703  *
704  */
705      if (OpenTileFile(NETHACK_PLANAR_TILEFILE, FALSE)) tilefailure |= 1;
706      if (OpenTileFile(NETHACK_OVERVIEW_TILEFILE, TRUE)) tilefailure |= 2;       
707      if (ReadTileFileHeader(&tibheader, FALSE)) tilefailure |= 4;
708
709      if (tilefailure) {
710         raw_printf("Reverting to TTY mode, tile initialization failure (%d).",
711                 tilefailure);
712         wait_synch();
713         iflags.usevga = 0;
714         iflags.tile_view = FALSE;
715         iflags.over_view = FALSE;
716         CO = 80;
717         LI = 25;
718 /*      clear_screen()  */ /* not vga_clear_screen() */
719         return;
720      }
721 #   endif
722
723      if (iflags.usevga) {
724         for (i=0; i < SCREENHEIGHT; ++i) {
725                 screentable[i]=MK_PTR(VIDEOSEG, (i * SCREENBYTES));
726         }
727      }
728      vga_SwitchMode(MODE640x480);
729      windowprocs.win_cliparound = vga_cliparound;
730 /*     vga_NoBorder(BACKGROUND_VGA_COLOR); */  /* Not needed after palette mod */
731 #   ifdef USE_TILES
732      paletteptr = tibheader.palette;
733      iflags.tile_view = TRUE;
734      iflags.over_view = FALSE;
735 #   else
736      paletteptr = defpalette;
737 #   endif
738      vga_SetPalette(paletteptr);
739      g_attribute  = attrib_gr_normal;
740      font = vga_FontPtrs();
741      clear_screen();
742      clipx = 0;
743      clipxmax = clipx + (viewport_size - 1);
744 }
745
746 /*
747  * Switches modes of the video card.
748  *
749  * If mode == MODETEXT (0x03), then the card is placed into text
750  * mode.  If mode == 640x480, then the card is placed into vga
751  * mode (video mode 0x12). No other modes are currently supported.
752  *
753  */
754 void vga_SwitchMode(unsigned int mode)
755 {
756         union REGS regs;
757
758         if ((mode == MODE640x480) || (mode == MODETEXT)) {
759                 if (iflags.usevga && (mode == MODE640x480)) {
760                         iflags.grmode = 1;
761                 } else {
762                         iflags.grmode = 0;
763                 }
764                 regs.x.ax = mode;
765                 (void) int86(VIDEO_BIOS, &regs, &regs);
766         } else {
767                 iflags.grmode = 0;      /* force text mode for error msg */
768                 regs.x.ax = MODETEXT;
769                 (void) int86(VIDEO_BIOS, &regs, &regs);
770                 g_attribute  = attrib_text_normal;
771                 impossible("vga_SwitchMode: Bad video mode requested 0x%X",
772                         mode);
773         }
774 }
775
776 /*
777  * This allows grouping of several tasks to be done when
778  * switching back to text mode. This is a public (extern) function.
779  *
780  */
781 void vga_Finish(void)
782 {
783      CloseTileFile(0);
784      CloseTileFile(1);
785      vga_SwitchMode(MODETEXT);
786      windowprocs.win_cliparound = tty_cliparound;
787      g_attribute  = attrib_text_normal;
788      iflags.tile_view = FALSE;
789 }
790
791 #if 0
792 /*
793  * Turn off any border colour that might be enabled in the VGA card
794  * register.
795  *
796  * I disabled this after modifying tile2bin.c to remap black & white
797  * to a more standard values - MJA 94/04/23.
798  *
799  */
800 STATIC_OVL void 
801 vga_NoBorder(int bc)
802 {
803         union REGS regs;
804
805         regs.h.ah = (char)0x10;
806         regs.h.al = (char)0x01;
807         regs.h.bh = (char)bc;
808         regs.h.bl = 0;
809         (void) int86(VIDEO_BIOS, &regs, &regs); 
810 }
811 #endif
812
813 /*
814  * 
815  * Returns a far pointer (or flat 32 bit pointer under djgpp) to the
816  * location of the appropriate ROM font for the _current_ video mode
817  * (so you must place the card into the desired video mode before
818  * calling this function).
819  *
820  * This function takes advantage of the video BIOS loading the
821  * address of the appropriate character definition table for
822  * the current graphics mode into interrupt vector 0x43 (0000:010C).
823  */
824 char __far  *vga_FontPtrs(void)
825 {
826         USHORT  __far *tmp;
827         char __far *retval;
828         USHORT fseg, foff;
829         tmp  = (USHORT __far *)MK_PTR(((USHORT)FONT_PTR_SEGMENT),
830                                         ((USHORT)FONT_PTR_OFFSET));
831         foff = READ_ABSOLUTE_WORD(tmp);
832         ++tmp;
833         fseg = READ_ABSOLUTE_WORD(tmp);
834         retval = (char __far *)MK_PTR(fseg,foff);
835         return retval;
836 }
837
838 /*
839  * This will verify the existance of a VGA adapter on the machine.
840  * Video function call 0x1a returns 0x1a in AL if successful, and
841  * returns the following values in BL for the active display:
842  *
843  * 0=no display, 1=MDA, 2=CGA, 4=EGA(color-monitor), 
844  * 5=EGA(mono-monitor), 6=PGA, 7=VGA(mono-monitor), 8=VGA(color-monitor),
845  * 0xB=MCGA(mono-monitor), 0xC=MCGA(color-monitor), 0xFF=unknown)
846  */
847 int vga_detect()
848 {
849         union REGS regs;
850         
851         regs.h.al = 0;
852         regs.h.ah = 0x1a;
853         (void) int86(VIDEO_BIOS, &regs, &regs);
854 /*
855  * debug
856  *
857  *      printf("vga_detect returned al=%02x, bh=%02x, bl=%02x\n",
858  *                      (int)regs.h.al, (int)regs.h.bh, (int)regs.h.bl);
859  *      getch();
860  */
861         if ((int)regs.h.al == 0x1a) { 
862                 if (((int)regs.h.bl == 8) || ((int)regs.h.bl == 7)) {
863                         return 1;
864                 }
865         }
866         return 0;
867 }
868
869 /*
870  * Write character 'ch', at (x,y) and
871  * do it using the colour 'colour'.
872  *
873  */
874 void 
875 vga_WriteChar(chr,col,row,colour)
876 int chr,col,row,colour;
877 {
878         int i;
879         int x,pixy;
880
881         char volatile tc;
882         char __far *cp;
883         unsigned char __far *fp = font;
884         unsigned char fnt;
885         int actual_colour = vgacmap[colour];
886
887
888         x = min(col,(CO-1));           /* min() used protection from callers */
889         pixy = min(row,(LI-1)) * 16; /* assumes 8 x 16 char set */
890 /*      if (chr < ' ') chr = ' ';  */  /* assumes ASCII set */
891
892         outportb(0x3ce,5);
893         outportb(0x3cf,2);
894                         
895         chr = chr<<4;
896         for (i=0; i < MAX_ROWS_PER_CELL; ++i) {
897                 cp = screentable[pixy+i] + x;
898                 fnt = READ_ABSOLUTE((fp + chr + i));
899                 outportb(0x3ce,8);
900                 outportb(0x3cf,fnt);
901                 tc = READ_ABSOLUTE(cp); /* wrt mode 2, must read, then write */
902                 WRITE_ABSOLUTE(cp, (char)actual_colour);
903                 outportb(0x3ce,8);
904                 outportb(0x3cf,~fnt);
905                 tc = READ_ABSOLUTE(cp); /* wrt mode 2, must read, then write */
906                 WRITE_ABSOLUTE(cp, (char)BACKGROUND_VGA_COLOR);
907         }
908         outportb(0x3ce,5);
909         outportb(0x3cf,0);
910         outportb(0x3ce,8);
911         outportb(0x3cf,255);
912 }
913
914 /*
915  * This is the routine that displays a high-res "cell" pointed to by 'gp'
916  * at the desired location (col,row).
917  *
918  * Note: (col,row) in this case refer to the coordinate location in
919  * NetHack character grid terms, (ie. the 40 x 25 character grid),
920  * not the x,y pixel location.
921  *
922  */
923 void
924 vga_DisplayCell(gp,col,row)
925 struct planar_cell_struct *gp;
926 int col,row;
927 {
928         int i,pixx,pixy;
929         char __far *tmp_s;      /* source pointer */
930         char __far *tmp_d;      /* destination pointer */
931         int vplane;
932
933         pixy = row2y(row);              /* convert to pixels */
934         pixx = col2x(col);
935         for(vplane=0; vplane < SCREENPLANES; ++vplane) {
936                 egawriteplane(vp[vplane]);
937                 for(i=0;i < ROWS_PER_CELL; ++i) {
938                         tmp_d = screentable[i+pixy];
939                         tmp_d += pixx;
940                 /*
941                  * memcpy((void *)tmp,(void *)gp->plane[vplane].image[i],
942                  *         BYTES_PER_CELL);
943                  */
944                         tmp_s = gp->plane[vplane].image[i];
945                         WRITE_ABSOLUTE(tmp_d, (*tmp_s));
946                         ++tmp_s; ++tmp_d;
947                         WRITE_ABSOLUTE(tmp_d, (*tmp_s));
948                 }
949         }
950         egawriteplane(15);
951 }
952
953 void
954 vga_DisplayCell_O(gp,col,row)
955 struct overview_planar_cell_struct *gp;
956 int col,row;
957 {
958         int i,pixx,pixy;
959         char __far *tmp_s;      /* source pointer */
960         char __far *tmp_d;      /* destination pointer */
961         int vplane;
962
963         pixy = row2y(row);              /* convert to pixels */
964         pixx = col;
965         for(vplane=0; vplane < SCREENPLANES; ++vplane) {
966                 egawriteplane(vp[vplane]);
967                 for(i=0;i < ROWS_PER_CELL; ++i) {
968                         tmp_d = screentable[i+pixy];
969                         tmp_d += pixx;
970                 /*
971                  * memcpy((void *)tmp,(void *)gp->plane[vplane].image[i],
972                  *         BYTES_PER_CELL);
973                  */
974                         tmp_s = gp->plane[vplane].image[i];
975                         WRITE_ABSOLUTE(tmp_d, (*tmp_s));
976                 }
977         }
978         egawriteplane(15);
979 }
980
981 /*
982  * Write the character string pointed to by 's', whose maximum length
983  * is 'len' at location (x,y) using the 'colour' colour.
984  *
985  */
986 void 
987 vga_WriteStr(s,len,col,row,colour)
988 char *s;
989 int len,col,row,colour;
990 {
991         unsigned char *us;
992         int i = 0;
993
994         /* protection from callers */
995         if (row > (LI-1)) return;
996
997         i  = 0;
998         us = (unsigned char *)s;
999         while( (*us != 0) && (i < len) && (col < (CO - 1))) {
1000                 vga_WriteChar(*us,col,row,colour);
1001                 ++us;
1002                 ++i;
1003                 ++col;
1004         }
1005 }
1006
1007 # endif /* OVLB */
1008
1009
1010 # ifdef OVLB
1011 /*
1012  * Initialize the VGA palette with the desired colours. This
1013  * must be a series of 48 bytes for use with a card in
1014  * 16 colour mode at 640 x 480.
1015  *
1016  */
1017 void
1018 vga_SetPalette(p)
1019         char *p;
1020 {
1021         union REGS regs;
1022         int i;
1023
1024         outportb(0x3c6,0xff);
1025         for(i=0;i < COLORDEPTH; ++i) {
1026                 outportb(0x3c8,i);
1027                 outportb(0x3c9,(*p++) >> 2);
1028                 outportb(0x3c9,(*p++) >> 2);
1029                 outportb(0x3c9,(*p++) >> 2);
1030         }
1031         regs.x.bx = 0x0000;
1032         for(i=0;i < COLORDEPTH; ++i) {
1033                 regs.x.ax = 0x1000;
1034                 (void) int86(VIDEO_BIOS,&regs,&regs);
1035                 regs.x.bx += 0x0101;
1036         }
1037 }
1038
1039 /*static unsigned char colorbits[]={0x01,0x02,0x04,0x08}; */ /* wrong */
1040 static unsigned char colorbits[]={0x08,0x04,0x02,0x01}; 
1041
1042 #ifdef POSITIONBAR
1043
1044 #define PBAR_ROW (LI - 4)
1045 #define PBAR_COLOR_ON     15    /* slate grey background colour of tiles */
1046 #define PBAR_COLOR_OFF    12    /* bluish grey, used in old style only */
1047 #define PBAR_COLOR_STAIRS  9    /* brown */
1048 #define PBAR_COLOR_HERO   14    /* creamy white */
1049
1050 static unsigned char pbar[COLNO];
1051
1052 void 
1053 vga_update_positionbar(posbar)
1054 char *posbar;
1055 {
1056         char *p = pbar;
1057         if (posbar) while (*posbar) *p++ = *posbar++;
1058         *p = 0;
1059 }
1060
1061 STATIC_OVL void 
1062 positionbar()
1063 {
1064         char *posbar = pbar;
1065         int feature, ucol;
1066         int k, y, colour, row;
1067         char __far *pch;
1068
1069         int startk, stopk;
1070         char volatile a;
1071         boolean nowhere = FALSE;
1072         int pixy = (PBAR_ROW * MAX_ROWS_PER_CELL);
1073         int tmp;
1074
1075         if (!iflags.grmode || !iflags.tile_view) return;
1076         if ((clipx < 0)  || (clipxmax <= 0) || (clipx >= clipxmax)) 
1077                 nowhere = TRUE;
1078         if (nowhere) {
1079 #ifdef DEBUG
1080                 pline("Would have put bar using %d - %d.",clipx,clipxmax);
1081 #endif
1082                 return;
1083         }
1084 #ifdef OLD_STYLE
1085         outportb(0x3ce,5);
1086         outportb(0x3cf,2);
1087         for (y=pixy; y < (pixy + MAX_ROWS_PER_CELL); ++y) {
1088                 pch = screentable[y];
1089                 for (k=0; k < SCREENBYTES; ++k) {
1090                         if ((k < clipx) || (k > clipxmax)) {
1091                                 colour = PBAR_COLOR_OFF;                        
1092                         } else colour = PBAR_COLOR_ON;
1093                         outportb(0x3ce,8);
1094                         outportb(0x3cf,255);
1095                         a = READ_ABSOLUTE(pch); /* Must read , then write */
1096                         WRITE_ABSOLUTE(pch, (char)colour);
1097                         ++pch;
1098                 }
1099         }
1100         outportb(0x3ce,5);
1101         outportb(0x3cf,0);
1102 #else
1103         colour = PBAR_COLOR_ON;
1104         outportb(0x3ce,5);
1105         outportb(0x3cf,2);
1106         for (y=pixy, row = 0; y < (pixy + MAX_ROWS_PER_CELL); ++y, ++row) {
1107                 pch = screentable[y];
1108                 if ((!row) || (row == (ROWS_PER_CELL-1))) {
1109                         startk = 0;
1110                         stopk  = SCREENBYTES;
1111                 } else {
1112                         startk = clipx;
1113                         stopk  = clipxmax;
1114                 }
1115                 for (k=0; k < SCREENBYTES; ++k) {
1116                         if ((k < startk) || (k > stopk))
1117                                 colour = BACKGROUND_VGA_COLOR;
1118                         else
1119                                 colour = PBAR_COLOR_ON;
1120                         outportb(0x3ce,8);
1121                         outportb(0x3cf,255);
1122                         a = READ_ABSOLUTE(pch); /* Must read , then write */
1123                         WRITE_ABSOLUTE(pch, (char)colour);
1124                         ++pch;
1125                 }
1126         }
1127         outportb(0x3ce,5);
1128         outportb(0x3cf,0);
1129 #endif
1130         ucol = 0;
1131         if (posbar) {
1132             while (*posbar != 0) {
1133                 feature = *posbar++;
1134                 switch (feature) {
1135                     case '>':
1136                         vga_special(feature, (int)*posbar++, PBAR_COLOR_STAIRS);
1137                         break;
1138                     case '<':
1139                         vga_special(feature, (int)*posbar++, PBAR_COLOR_STAIRS);
1140                         break;
1141                     case '@':
1142                         ucol = (int)*posbar++;
1143                         vga_special(feature, ucol, PBAR_COLOR_HERO);
1144                         break;
1145                     default: /* unanticipated symbols */
1146                         vga_special(feature, (int)*posbar++, PBAR_COLOR_STAIRS);
1147                         break;
1148                 }
1149             }
1150         }
1151 #  ifdef SIMULATE_CURSOR
1152         if (inmap) {
1153                 tmp = curcol + 1;
1154                 if ((tmp != ucol) && (curcol >= 0))     
1155                         vga_special('_', tmp, PBAR_COLOR_HERO);
1156         }
1157 #  endif
1158 }
1159
1160 void
1161 vga_special(chr,col,color)
1162 int chr,col,color;
1163 {
1164         int i,y,pixy;
1165         char __far *tmp_d;      /* destination pointer */
1166         int vplane;
1167         char fnt;
1168         char bits[SCREENPLANES][ROWS_PER_CELL];
1169
1170         pixy = PBAR_ROW * MAX_ROWS_PER_CELL;
1171         for(vplane=0; vplane < SCREENPLANES; ++vplane) {
1172                 egareadplane(vplane);
1173                 y = pixy;
1174                 for(i=0;i < ROWS_PER_CELL; ++i) {
1175                         tmp_d = screentable[y++] + col;
1176                         bits[vplane][i] = READ_ABSOLUTE(tmp_d);
1177                         fnt = READ_ABSOLUTE((font + ((chr<<4) + i)));
1178                         if (colorbits[vplane] & color)
1179                                 bits[vplane][i] |= fnt;
1180                         else
1181                                 bits[vplane][i] &= ~fnt;
1182                 }
1183         }
1184         for(vplane=0; vplane < SCREENPLANES; ++vplane) {
1185                 egawriteplane(vp[vplane]);
1186                 y = pixy;
1187                 for(i=0;i < ROWS_PER_CELL; ++i) {
1188                         tmp_d = screentable[y++] + col;
1189                         WRITE_ABSOLUTE(tmp_d, (bits[vplane][i]));
1190                 }
1191         }
1192         egawriteplane(15);
1193 }
1194
1195 #  endif POSITIONBAR
1196
1197 #  ifdef SIMULATE_CURSOR
1198
1199 static struct planar_cell_struct undercursor;
1200 static struct planar_cell_struct cursor;
1201
1202 void
1203 vga_DrawCursor()
1204 {
1205         int i,pixx,pixy,x,y,p;
1206         char __far *tmp1;
1207         char __far *tmp2;
1208         unsigned char first,second;
1209 /*      char on[2] =  {0xFF,0xFF}; */
1210 /*      char off[2] = {0x00,0x00}; */
1211 #ifdef REINCARNATION
1212         boolean isrogue = Is_rogue_level(&u.uz);
1213         boolean singlebyte = (isrogue || iflags.over_view
1214                               || iflags.traditional_view || !inmap);
1215 #else
1216         boolean singlebyte = (iflags.over_view
1217                               || iflags.traditional_view || !inmap);
1218 #endif
1219         int curtyp;
1220
1221         if (!cursor_type && inmap) return;      /* CURSOR_INVIS - nothing to do */
1222
1223         x = min(curcol,(CO - 1)); /* protection from callers */
1224         y = min(currow,(LI - 1));                 /* protection from callers */
1225         if (!singlebyte && ((x < clipx) || (x > clipxmax))) return;
1226             pixy = row2y(y);              /* convert to pixels */
1227             if (singlebyte)
1228                     pixx = x;
1229             else
1230                     pixx = col2x((x-clipx));
1231
1232             for(i=0;i < ROWS_PER_CELL; ++i) {
1233                 tmp1 = screentable[i+pixy];
1234                 tmp1 += pixx;
1235                 tmp2 = tmp1 + 1;
1236                 egareadplane(3);
1237                 /* memcpy(undercursor.plane[3].image[i],tmp1,BYTES_PER_CELL); */
1238                 undercursor.plane[3].image[i][0] = READ_ABSOLUTE(tmp1);
1239                 if (!singlebyte)
1240                         undercursor.plane[3].image[i][1] = READ_ABSOLUTE(tmp2);
1241
1242                 egareadplane(2);
1243                 /* memcpy(undercursor.plane[2].image[i],tmp1,BYTES_PER_CELL); */
1244                 undercursor.plane[2].image[i][0] = READ_ABSOLUTE(tmp1);
1245                 if (!singlebyte)
1246                         undercursor.plane[2].image[i][1] = READ_ABSOLUTE(tmp2);
1247
1248                 egareadplane(1);
1249                 /* memcpy(undercursor.plane[1].image[i],tmp1,BYTES_PER_CELL); */
1250                 undercursor.plane[1].image[i][0] = READ_ABSOLUTE(tmp1);
1251                 if (!singlebyte)
1252                         undercursor.plane[1].image[i][1] = READ_ABSOLUTE(tmp2);
1253
1254                 egareadplane(0);
1255                 /* memcpy(undercursor.plane[0].image[i],tmp1,BYTES_PER_CELL); */
1256                 undercursor.plane[0].image[i][0] = READ_ABSOLUTE(tmp1);
1257                 if (!singlebyte)
1258                         undercursor.plane[0].image[i][1] = READ_ABSOLUTE(tmp2);
1259             }
1260
1261             /*
1262              * Now we have a snapshot of the current cell.
1263              * Make a copy of it, then manipulate the copy
1264              * to include the cursor, and place the tinkered
1265              * version on the display.
1266              */ 
1267
1268             cursor = undercursor;
1269             if (inmap) curtyp = cursor_type;
1270             else curtyp = CURSOR_UNDERLINE;
1271
1272             switch(curtyp) {
1273
1274                 case CURSOR_CORNER:
1275                     for(i = 0; i < 2; ++i) {
1276                         if (!i) {
1277                                 if (singlebyte) first = 0xC3;
1278                                 else first  = 0xC0;
1279                                 second = 0x03;
1280                         } else {
1281                                 if (singlebyte) first = 0x81;
1282                                 else first  = 0x80;
1283                                 second = 0x01;
1284                         }
1285                         for (p=0; p < 4; ++p) {
1286                                 if (cursor_color & colorbits[p]) {
1287                                         cursor.plane[p].image[i][0] |= first;
1288                                         if (!singlebyte)
1289                                         cursor.plane[p].image[i][1] |= second;
1290                                 } else {
1291                                         cursor.plane[p].image[i][0] &= ~first;
1292                                         if (!singlebyte)
1293                                         cursor.plane[p].image[i][1] &= ~second;
1294                                 }
1295                         }
1296                     }
1297
1298                     for(i = ROWS_PER_CELL - 2; i < ROWS_PER_CELL; ++i) {
1299                         if (i != (ROWS_PER_CELL-1)) {
1300                                 if (singlebyte) first = 0x81;
1301                                 else first  = 0x80;
1302                                 second = 0x01;
1303                         } else {
1304                                 if (singlebyte) first = 0xC3;
1305                                 else first  = 0xC0;
1306                                 second = 0x03;
1307                         }
1308                         for (p=0; p < SCREENPLANES; ++p) {
1309                                 if (cursor_color & colorbits[p]) {
1310                                         cursor.plane[p].image[i][0] |= first;
1311                                         if (!singlebyte)
1312                                         cursor.plane[p].image[i][1] |= second;
1313                                 } else {
1314                                         cursor.plane[p].image[i][0] &= ~first;
1315                                         if (!singlebyte)
1316                                         cursor.plane[p].image[i][1] &= ~second;
1317                                 }
1318                         }
1319                     }
1320                     break;
1321
1322                 case CURSOR_UNDERLINE:
1323
1324                     i = ROWS_PER_CELL - 1;
1325                     first  = 0xFF;
1326                     second = 0xFF;
1327                     for (p=0; p < SCREENPLANES; ++p) {
1328                         if (cursor_color & colorbits[p]) {
1329                                 cursor.plane[p].image[i][0] |= first;
1330                                 if (!singlebyte)
1331                                 cursor.plane[p].image[i][1] |= second;
1332                         } else {
1333                                 cursor.plane[p].image[i][0] &= ~first;
1334                                 if (!singlebyte)
1335                                 cursor.plane[p].image[i][1] &= ~second;
1336                         }
1337                     }
1338                     break;
1339
1340                 case CURSOR_FRAME:
1341
1342                     /* fall through */
1343
1344                 default:                        
1345                     for(i = 0; i < ROWS_PER_CELL; ++i) {
1346
1347                         if ((i == 0) || (i == (ROWS_PER_CELL-1))) {
1348                                 first  = 0xFF;
1349                                 second = 0xFF;
1350                         } else {
1351                                 if (singlebyte) first = 0x81;
1352                                 else first  = 0x80;
1353                                 second = 0x01;
1354                         }
1355                         for (p=0; p < SCREENPLANES; ++p) {
1356                                 if (cursor_color & colorbits[p]) {
1357                                         cursor.plane[p].image[i][0] |= first;
1358                                         if (!singlebyte)
1359                                         cursor.plane[p].image[i][1] |= second;
1360                                 } else {
1361                                         cursor.plane[p].image[i][0] &= ~first;
1362                                         if (!singlebyte)
1363                                         cursor.plane[p].image[i][1] &= ~second;
1364                                 }
1365                         }
1366                     }
1367                     break;
1368             }
1369
1370            /*
1371             * Place the new cell onto the display.
1372             *
1373             */
1374             
1375             for(i=0;i < ROWS_PER_CELL; ++i) {
1376                 tmp1 = screentable[i+pixy];
1377                 tmp1 += pixx;
1378                 tmp2 = tmp1 + 1;
1379                 egawriteplane(8);
1380                 /* memcpy(tmp1,cursor.plane[3].image[i],BYTES_PER_CELL); */
1381                 WRITE_ABSOLUTE(tmp1,cursor.plane[3].image[i][0]);
1382                 if (!singlebyte)
1383                 WRITE_ABSOLUTE(tmp2,cursor.plane[3].image[i][1]);
1384
1385                 egawriteplane(4);
1386                 /* memcpy(tmp1,cursor.plane[2].image[i],BYTES_PER_CELL); */
1387                 WRITE_ABSOLUTE(tmp1,cursor.plane[2].image[i][0]);
1388                 if (!singlebyte)
1389                 WRITE_ABSOLUTE(tmp2,cursor.plane[2].image[i][1]);
1390
1391                 egawriteplane(2);
1392                 /* memcpy(tmp1,cursor.plane[1].image[i],BYTES_PER_CELL); */
1393                 WRITE_ABSOLUTE(tmp1,cursor.plane[1].image[i][0]);
1394                 if (!singlebyte)
1395                 WRITE_ABSOLUTE(tmp2,cursor.plane[1].image[i][1]);
1396
1397                 egawriteplane(1);
1398                 /* memcpy(tmp1,cursor.plane[0].image[i],BYTES_PER_CELL); */
1399                 WRITE_ABSOLUTE(tmp1,cursor.plane[0].image[i][0]);
1400                 if (!singlebyte)
1401                 WRITE_ABSOLUTE(tmp2,cursor.plane[0].image[i][1]);
1402             }
1403             egawriteplane(15);
1404 #ifdef POSITIONBAR
1405             if (inmap) positionbar();
1406 #endif
1407 }
1408
1409 void
1410 vga_HideCursor()
1411 {
1412
1413         int i,pixx,pixy,x,y;
1414         char __far *tmp1;
1415         char __far *tmp2;
1416 #ifdef REINCARNATION
1417         boolean isrogue = Is_rogue_level(&u.uz);
1418         boolean singlebyte = (isrogue || iflags.over_view
1419                               || iflags.traditional_view || !inmap);
1420 #else
1421         boolean singlebyte = (iflags.over_view
1422                               || iflags.traditional_view || !inmap);
1423 #endif
1424         int curtyp;
1425         
1426         if (inmap && !cursor_type) return;      /* CURSOR_INVIS - nothing to do */
1427         /* protection from callers */
1428         x = min(curcol,(CO - 1)); 
1429         y = min(currow,(LI-1));
1430         if (!singlebyte && ((x < clipx) || (x > clipxmax))) return;
1431
1432             pixy = row2y(y);            /* convert to pixels */
1433             if (singlebyte)
1434                     pixx = x;
1435             else
1436                     pixx = col2x((x-clipx));
1437
1438             if (inmap) curtyp = cursor_type;
1439             else curtyp = CURSOR_UNDERLINE;
1440
1441             if (curtyp == CURSOR_UNDERLINE)  /* optimization for uline */
1442                 i = ROWS_PER_CELL - 1;
1443             else
1444                 i = 0;
1445
1446             for(;i < ROWS_PER_CELL; ++i) {
1447                 tmp1 = screentable[i+pixy];
1448                 tmp1 += pixx;
1449                 tmp2 = tmp1 + 1;
1450                 egawriteplane(8);
1451                 /* memcpy(tmp,undercursor.plane[3].image[i],BYTES_PER_CELL); */
1452                 WRITE_ABSOLUTE(tmp1,undercursor.plane[3].image[i][0]);
1453                 if (!singlebyte)
1454                 WRITE_ABSOLUTE(tmp2,undercursor.plane[3].image[i][1]);
1455
1456                 egawriteplane(4);
1457                 /* memcpy(tmp,undercursor.plane[2].image[i],BYTES_PER_CELL); */
1458                 WRITE_ABSOLUTE(tmp1,undercursor.plane[2].image[i][0]);
1459                 if (!singlebyte)
1460                 WRITE_ABSOLUTE(tmp2,undercursor.plane[2].image[i][1]);
1461
1462                 egawriteplane(2);
1463                 /* memcpy(tmp,undercursor.plane[1].image[i],BYTES_PER_CELL); */
1464                 WRITE_ABSOLUTE(tmp1,undercursor.plane[1].image[i][0]);
1465                 if (!singlebyte)
1466                 WRITE_ABSOLUTE(tmp2,undercursor.plane[1].image[i][1]);
1467
1468                 egawriteplane(1);
1469                 /* memcpy(tmp,undercursor.plane[0].image[i],BYTES_PER_CELL); */
1470                 WRITE_ABSOLUTE(tmp1,undercursor.plane[0].image[i][0]);
1471                 if (!singlebyte)
1472                 WRITE_ABSOLUTE(tmp2,undercursor.plane[0].image[i][1]);
1473             }
1474             egawriteplane(15);
1475 }
1476 #  endif /* SIMULATE_CURSOR */
1477 # endif /* OVLB */
1478 #endif /* SCREEN_VGA  */
1479
1480 /* vidvga.c */