1 /* NetHack 3.7	video.c	$NHDT-Date: 1596498277 2020/08/03 23:44:37 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.16 $ */
2 /*   Copyright (c) NetHack PC Development Team 1993, 1994, 2001	    */
3 /*   NetHack may be freely redistributed.  See license for details. */
4 /*								    */
5 /*
6  * video.c - Hardware video support front-ends
7  *
8  *Edit History:
9  *     Initial Creation 	     M. Allison      1993/04/04
10  *     Add djgpp support	     K. Smolkowski   1993/04/26
11  *     Add txt/graphics mode support M. Allison      1993/10/30
12  *     Add graphics mode cursor sim. M. Allison      1994/02/19
13  *     Add hooks for decals on vga   M. Allison      2001/04/07
14  */
15 
16 #include "hack.h"
17 
18 #ifndef STUBVIDEO
19 #include "pcvideo.h"
20 #include "pctiles.h"
21 
22 #if defined(_MSC_VER)
23 #if _MSC_VER >= 700
24 #pragma warning(disable : 4018) /* signed/unsigned mismatch */
25 #pragma warning(disable : 4127) /* conditional expression is constant */
26 #pragma warning(disable : 4131) /* old style declarator */
27 #pragma warning(disable : 4305) /* prevents complaints with MK_FP */
28 #pragma warning(disable : 4309) /* initializing */
29 #pragma warning(disable : 4759) /* prevents complaints with MK_FP */
30 #endif
31 #endif
32 /*=========================================================================
33  * General PC Video routines.
34  *
35  * The following routines are the video interfacing functions.
36  * In general these make calls to more hardware specific
37  * routines in other source files.
38  *
39  * Assumptions (94/04/23):
40  *
41  *   - Supported defaults.nh file video options:
42  *
43  *          If OPTIONS=video:autodetect is defined in defaults.nh then
44  *          check for a VGA video adapter.  If one is detected, then
45  *          use the VGA code, otherwise resort to using the 'standard'
46  *          video BIOS routines.
47  *
48  *          If OPTIONS=video:vga is defined in defaults.nh, then use
49  *          the VGA code.
50  *
51  *          If OPTIONS=video:default is defined in defaults.nh use the
52  *          'standard' video BIOS routines (in the overlaid version),
53  *          or DJGPPFAST routines (under djgpp). This is equivalent to
54  *          having no OPTIONS=video:xxxx entry at all.
55  *
56  * Notes (94/04/23):
57  *
58  *   - The handler for defaults.nh file entry:
59  *
60  *           OPTIONS=video:xxxxx
61  *
62  *     has now been added.  The handler is in video.c and is called
63  *     from options.c.
64  *
65  *   - Handling of videocolors and videoshades are now done with
66  *     OPTIONS= statements.  The new syntax separates the colour
67  *     values with dashes ('-') rather than spaces (' ').
68  *
69  * To Do (94/04/23):
70  *
71  *
72  *=========================================================================
73  */
74 
75 void
get_scr_size(void)76 get_scr_size(void)
77 {
78 #ifdef SCREEN_VGA
79     if (iflags.usevga) {
80         vga_get_scr_size();
81     } else
82 #endif
83 #ifdef SCREEN_VESA
84     if (iflags.usevesa) {
85         vesa_get_scr_size();
86     } else
87 #endif
88         txt_get_scr_size();
89 }
90 
91 /*
92  * --------------------------------------------------------------
93  * The rest of this file is only compiled if NO_TERMS is defined.
94  * --------------------------------------------------------------
95  */
96 
97 #ifdef NO_TERMS
98 
99 #include <ctype.h>
100 #include "wintty.h"
101 
102 #ifdef __GO32__
103 #include <pc.h>
104 #include <unistd.h>
105 #if !(__DJGPP__ >= 2)
106 typedef long clock_t;
107 #endif
108 #endif
109 
110 #ifdef __BORLANDC__
111 #include <dos.h> /* needed for delay() */
112 #endif
113 
114 #ifdef SCREEN_DJGPPFAST /* parts of this block may be unecessary now */
115 #define get_cursor(x, y) ScreenGetCursor(y, x)
116 #endif
117 
118 #ifdef SCREEN_BIOS
119 void get_cursor(int *, int *);
120 #endif
121 
122 void adjust_cursor_flags(struct WinDesc *);
123 void cmov(int, int);
124 void nocmov(int, int);
125 static void init_ttycolor(void);
126 
127 int savevmode;               /* store the original video mode in here */
128 int curcol, currow;          /* graphics mode current cursor locations */
129 int g_attribute;             /* Current attribute to use */
130 int monoflag;                /* 0 = not monochrome, else monochrome */
131 int attrib_text_normal;      /* text mode normal attribute */
132 int attrib_gr_normal;        /* graphics mode normal attribute */
133 int attrib_text_intense;     /* text mode intense attribute */
134 int attrib_gr_intense;       /* graphics mode intense attribute */
135 boolean traditional = FALSE; /* traditonal TTY character mode */
136 boolean inmap = FALSE;       /* in the map window */
137 #ifdef TEXTCOLOR
138 char ttycolors[CLR_MAX]; /* also used/set in options.c */
139 #endif                   /* TEXTCOLOR */
140 
141 void
backsp(void)142 backsp(void)
143 {
144     if (!iflags.grmode) {
145         txt_backsp();
146 #ifdef SCREEN_VGA
147     } else if (iflags.usevga) {
148         vga_backsp();
149 #endif
150 #ifdef SCREEN_VESA
151     } else if (iflags.usevesa) {
152         vesa_backsp();
153 #endif
154     }
155 }
156 
157 void
clear_screen(void)158 clear_screen(void)
159 {
160     if (!iflags.grmode) {
161         txt_clear_screen();
162 #ifdef SCREEN_VGA
163     } else if (iflags.usevga) {
164         vga_clear_screen(BACKGROUND_VGA_COLOR);
165 #endif
166 #ifdef SCREEN_VESA
167     } else if (iflags.usevesa) {
168         vesa_clear_screen(BACKGROUND_VGA_COLOR);
169 #endif
170     }
171 }
172 
cl_end(void)173 void cl_end(void) /* clear to end of line */
174 {
175     int col, row;
176 
177     col = (int) ttyDisplay->curx;
178     row = (int) ttyDisplay->cury;
179     if (!iflags.grmode) {
180         txt_cl_end(col, row);
181 #ifdef SCREEN_VGA
182     } else if (iflags.usevga) {
183         vga_cl_end(col, row);
184 #endif
185 #ifdef SCREEN_VESA
186     } else if (iflags.usevesa) {
187         vesa_cl_end(col, row);
188 #endif
189     }
190     tty_curs(BASE_WINDOW, (int) ttyDisplay->curx + 1, (int) ttyDisplay->cury);
191 }
192 
cl_eos(void)193 void cl_eos(void) /* clear to end of screen */
194 {
195     int cy = (int) ttyDisplay->cury + 1;
196 
197     if (!iflags.grmode) {
198         txt_cl_eos();
199 #ifdef SCREEN_VGA
200     } else if (iflags.usevga) {
201         vga_cl_eos(cy);
202 #endif
203 #ifdef SCREEN_VESA
204     } else if (iflags.usevesa) {
205         vesa_cl_eos(cy);
206 #endif
207     }
208     tty_curs(BASE_WINDOW, (int) ttyDisplay->curx + 1, (int) ttyDisplay->cury);
209 }
210 
211 void
cmov(int col,int row)212 cmov(int col, int row)
213 {
214     ttyDisplay->cury = (uchar) row;
215     ttyDisplay->curx = (uchar) col;
216     if (!iflags.grmode) {
217         txt_gotoxy(col, row);
218 #ifdef SCREEN_VGA
219     } else if (iflags.usevga) {
220         vga_gotoloc(col, row);
221 #endif
222 #ifdef SCREEN_VESA
223     } else if (iflags.usevesa) {
224         vesa_gotoloc(col, row);
225 #endif
226     }
227 }
228 
229 #if 0
230 int
231 has_color(int color)
232 {
233     ++color; /* prevents compiler warning (unref. param) */
234 #ifdef TEXTCOLOR
235     return (monoflag) ? 0 : 1;
236 #else
237     return 0;
238 #endif
239 }
240 #endif
241 
242 void
home(void)243 home(void)
244 {
245     tty_curs(BASE_WINDOW, 1, 0);
246     ttyDisplay->curx = ttyDisplay->cury = (uchar) 0;
247     if (!iflags.grmode) {
248         txt_gotoxy(0, 0);
249 #ifdef SCREEN_VGA
250     } else if (iflags.usevga) {
251         vga_gotoloc(0, 0);
252 #endif
253 #ifdef SCREEN_VESA
254     } else if (iflags.usevesa) {
255         vesa_gotoloc(0, 0);
256 #endif
257     }
258 }
259 
260 void
nocmov(int col,int row)261 nocmov(int col, int row)
262 {
263     if (!iflags.grmode) {
264         txt_gotoxy(col, row);
265 #ifdef SCREEN_VGA
266     } else if (iflags.usevga) {
267         vga_gotoloc(col, row);
268 #endif
269 #ifdef SCREEN_VESA
270     } else if (iflags.usevesa) {
271         vesa_gotoloc(col, row);
272 #endif
273     }
274 }
275 
276 void
standoutbeg(void)277 standoutbeg(void)
278 {
279     g_attribute = iflags.grmode ? attrib_gr_intense : attrib_text_intense;
280 }
281 
282 void
standoutend(void)283 standoutend(void)
284 {
285     g_attribute = iflags.grmode ? attrib_gr_normal : attrib_text_normal;
286 }
287 
288 int
term_attr_fixup(int attrmask)289 term_attr_fixup(int attrmask)
290 {
291     return attrmask;
292 }
293 
294 void
term_end_attr(int attr)295 term_end_attr(int attr)
296 {
297     switch (attr) {
298     case ATR_ULINE:
299     case ATR_BOLD:
300     case ATR_BLINK:
301     case ATR_INVERSE:
302     default:
303         g_attribute = iflags.grmode ? attrib_gr_normal : attrib_text_normal;
304     }
305 }
306 
307 void
term_end_color(void)308 term_end_color(void)
309 {
310     g_attribute = iflags.grmode ? attrib_gr_normal : attrib_text_normal;
311 }
312 
313 void
term_end_raw_bold(void)314 term_end_raw_bold(void)
315 {
316     standoutend();
317 }
318 
319 void
term_start_attr(int attr)320 term_start_attr(int attr)
321 {
322     switch (attr) {
323     case ATR_ULINE:
324         if (monoflag) {
325             g_attribute = ATTRIB_MONO_UNDERLINE;
326         } else {
327             g_attribute =
328                 iflags.grmode ? attrib_gr_intense : attrib_text_intense;
329         }
330         break;
331     case ATR_BOLD:
332         g_attribute = iflags.grmode ? attrib_gr_intense : attrib_text_intense;
333         break;
334     case ATR_BLINK:
335         if (monoflag) {
336             g_attribute = ATTRIB_MONO_BLINK;
337         } else {
338             g_attribute =
339                 iflags.grmode ? attrib_gr_intense : attrib_text_intense;
340         }
341         break;
342     case ATR_INVERSE:
343         if (monoflag) {
344             g_attribute = ATTRIB_MONO_REVERSE;
345         } else {
346             g_attribute =
347                 iflags.grmode ? attrib_gr_intense : attrib_text_intense;
348         }
349         break;
350     default:
351         g_attribute = iflags.grmode ? attrib_gr_normal : attrib_text_normal;
352         break;
353     }
354 }
355 
356 void
term_start_color(int color)357 term_start_color(int color)
358 {
359 #ifdef TEXTCOLOR
360     if (monoflag) {
361         g_attribute = attrib_text_normal;
362     } else {
363         if (color >= 0 && color < CLR_MAX) {
364             if (iflags.grmode)
365                 g_attribute = color;
366             else
367                 g_attribute = ttycolors[color];
368         }
369     }
370 #endif
371 }
372 
373 void
term_start_raw_bold(void)374 term_start_raw_bold(void)
375 {
376     standoutbeg();
377 }
378 
379 void
tty_delay_output(void)380 tty_delay_output(void)
381 {
382 #ifdef TIMED_DELAY
383     if (flags.nap) {
384         (void) fflush(stdout);
385         msleep(50); /* sleep for 50 milliseconds */
386         return;
387     }
388 #endif
389 }
390 
391 void
tty_end_screen(void)392 tty_end_screen(void)
393 {
394     if (!iflags.grmode) {
395         txt_clear_screen();
396 #ifdef PC9800
397         fputs("\033[>1l", stdout);
398 #endif
399 #ifdef SCREEN_VGA
400     } else if (iflags.usevga) {
401         vga_tty_end_screen();
402 #endif
403 #ifdef SCREEN_VESA
404     } else if (iflags.usevesa) {
405         vesa_tty_end_screen();
406 #endif
407     }
408 }
409 
410 void
tty_nhbell(void)411 tty_nhbell(void)
412 {
413     txt_nhbell();
414 }
415 
416 void
tty_number_pad(int state)417 tty_number_pad(int state)
418 {
419     ++state; /* prevents compiler warning (unref. param) */
420 }
421 
422 void
tty_startup(int * wid,int * hgt)423 tty_startup(int *wid, int *hgt)
424 {
425     /* code to sense display adapter is required here - MJA */
426 
427     attrib_text_normal = ATTRIB_NORMAL;
428     attrib_text_intense = ATTRIB_INTENSE;
429 
430     /* These are defaults and may get overridden */
431     attrib_gr_normal = attrib_text_normal;
432     attrib_gr_intense = attrib_text_intense;
433     g_attribute = attrib_text_normal; /* Give it a starting value */
434 
435 #ifdef SCREEN_VGA
436     if (iflags.usevga) {
437         vga_tty_startup(wid, hgt);
438     } else
439 #endif
440 #ifdef SCREEN_VESA
441     if (iflags.usevesa) {
442         vesa_tty_startup(wid, hgt);
443     } else
444 #endif
445         txt_startup(wid, hgt);
446 
447     *wid = CO;
448     *hgt = LI;
449 
450 #ifdef CLIPPING
451     if (CO < COLNO || LI < ROWNO + 3)
452         setclipped();
453 #endif
454 
455 #ifdef TEXTCOLOR
456     init_ttycolor();
457 #endif
458 
459 #ifdef MONO_CHECK
460     monoflag = txt_monoadapt_check();
461 #else
462     monoflag = 0;
463 #endif
464 }
465 
466 void
tty_start_screen(void)467 tty_start_screen(void)
468 {
469 #ifdef PC9800
470     fputs("\033[>1h", stdout);
471 #endif
472     if (iflags.num_pad)
473         tty_number_pad(1); /* make keypad send digits */
474 }
475 
476 void
gr_init(void)477 gr_init(void)
478 {
479 #ifdef SCREEN_VGA
480     if (iflags.usevga) {
481         vga_Init();
482     } else
483 #endif
484 #ifdef SCREEN_VESA
485     if (iflags.usevesa) {
486         vesa_Init();
487     } else
488 #endif
489 #ifdef SCREEN_8514
490     if (iflags.use8514) {
491         v8514_Init();
492     } else
493 #endif
494     {}
495 }
496 
497 void
gr_finish(void)498 gr_finish(void)
499 {
500     if (iflags.grmode) {
501 #ifdef SCREEN_VGA
502         if (iflags.usevga) {
503             vga_Finish();
504         } else
505 #endif
506 #ifdef SCREEN_VESA
507         if (iflags.usevesa) {
508             vesa_Finish();
509         } else
510 #endif
511 #ifdef SCREEN_8514
512         if (iflags.use8514) {
513             v8514_Finish();
514         } else
515 #endif
516         {}
517     }
518 }
519 
520 /*
521  * Screen output routines (these are heavily used).
522  *
523  * These are the 3 routines used to place information on the screen
524  * in the NO_TERMS PC tty port of NetHack.  These are the routines
525  * that get called by routines in other NetHack source files (such
526  * as those in win/tty).
527  *
528  * xputs - Writes a c null terminated string at the current location.
529  *	   Depending on compile options, this could just be a series
530  *	   of repeated calls to xputc() for each character.
531  *
532  * xputc - Writes a single character at the current location. Since
533  *	   various places in the code assume that control characters
534  *	   can be used to control, we are forced to interpret some of
535  *	   the more common ones, in order to keep things looking correct.
536  *
537  * xputg - If using a graphics mode display mechanism (such as VGA, this
538  *	   routine is used to display a graphical representation of a
539  *	   NetHack glyph at the current location.  For more information on
540  *	   NetHack glyphs refer to the comments in include/display.h.
541  *
542  * NOTES:
543  *	   wintty.h uses macros to redefine common output functions
544  *	   such as puts, putc, putchar, so that they get steered into
545  *	   either xputs (for strings) or xputc (for single characters).
546  *	   References to puts, putc, and putchar in other source files
547  *	   (that include wintty.h) are actually using these routines.
548  */
549 
550 void
xputs(const char * s)551 xputs(const char *s)
552 {
553     int col, row;
554 
555     col = (int) ttyDisplay->curx;
556     row = (int) ttyDisplay->cury;
557 
558     if (!iflags.grmode) {
559         txt_xputs(s, col, row);
560 #ifdef SCREEN_VGA
561     } else if (iflags.usevga) {
562         vga_xputs(s, col, row);
563 #endif
564 #ifdef SCREEN_VESA
565     } else if (iflags.usevesa) {
566         vesa_xputs(s, col, row);
567 #endif
568     }
569 }
570 
571 /* same signature as 'putchar()' with potential failure result ignored */
572 int
xputc(int ch)573 xputc(int ch) /* write out character (and attribute) */
574 {
575     int i;
576     char attribute;
577 
578     i = iflags.grmode ? attrib_gr_normal : attrib_text_normal;
579 
580     attribute = (char) ((g_attribute == 0) ? i : g_attribute);
581     if (!iflags.grmode) {
582         txt_xputc(ch, attribute);
583 #ifdef SCREEN_VGA
584     } else if (iflags.usevga) {
585         vga_xputc(ch, attribute);
586 #endif /*SCREEN_VGA*/
587 #ifdef SCREEN_VESA
588     } else if (iflags.usevesa) {
589         vesa_xputc(ch, attribute);
590 #endif /*SCREEN_VESA*/
591     }
592     return 0;
593 }
594 
595 /* write out a glyph picture at current location */
xputg(int glyphnum,int ch,unsigned special)596 void xputg(int glyphnum, int ch, unsigned special)
597 {
598     if (!iflags.grmode || !iflags.tile_view) {
599         (void) xputc((char) ch);
600 #ifdef SCREEN_VGA
601     } else if (iflags.grmode && iflags.usevga) {
602         vga_xputg(glyphnum, ch, special);
603 #endif
604 #ifdef SCREEN_VESA
605     } else if (iflags.grmode && iflags.usevesa) {
606         vesa_xputg(glyphnum, ch, special);
607 #endif
608     }
609 }
610 
611 #ifdef POSITIONBAR
612 void
video_update_positionbar(char * posbar)613 video_update_positionbar(char *posbar)
614 {
615     if (!iflags.grmode)
616         return;
617 #ifdef SCREEN_VGA
618     else if (iflags.usevga)
619         vga_update_positionbar(posbar);
620 #endif
621 #ifdef SCREEN_VESA
622     else if (iflags.usevesa)
623         vesa_update_positionbar(posbar);
624 #endif
625 }
626 #endif
627 
628 void
adjust_cursor_flags(struct WinDesc * cw)629 adjust_cursor_flags(struct WinDesc *cw)
630 {
631 #ifdef SIMULATE_CURSOR
632 #if 0
633     if (cw->type == NHW_MAP) cursor_flag = 1;
634     else cursor_flag = 0;
635 #else
636     if (cw->type == NHW_MAP) {
637         inmap = 1;
638         cursor_flag = 1;
639     } else {
640         inmap = 0;
641         cursor_flag = 1;
642     }
643 #endif /* 0 */
644 #endif /* SIMULATE_CURSOR */
645 }
646 
647 #ifdef SIMULATE_CURSOR
648 
649 /* change the defaults in pcvideo.h, not here */
650 int cursor_type = CURSOR_DEFAULT_STYLE;
651 int cursor_color = CURSOR_DEFAULT_COLOR;
652 int cursor_flag;
653 
654 /* The check for iflags.grmode is made BEFORE calling these. */
655 void
DrawCursor(void)656 DrawCursor(void)
657 {
658 #ifdef SCREEN_VGA
659     if (iflags.usevga)
660         vga_DrawCursor();
661 #endif
662 #ifdef SCREEN_VESA
663     if (iflags.usevesa)
664         vesa_DrawCursor();
665 #endif
666 }
667 
668 void
HideCursor(void)669 HideCursor(void)
670 {
671 #ifdef SCREEN_VGA
672     if (iflags.usevga)
673         vga_HideCursor();
674 #endif
675 #ifdef SCREEN_VESA
676     if (iflags.usevesa)
677         vesa_HideCursor();
678 #endif
679 }
680 
681 #endif /* SIMULATE_CURSOR */
682 
683 #ifdef TEXTCOLOR
684 /*
685  * CLR_BLACK		0
686  * CLR_RED		1
687  * CLR_GREEN		2
688  * CLR_BROWN		3	low-intensity yellow
689  * CLR_BLUE 		4
690  * CLR_MAGENTA		5
691  * CLR_CYAN 		6
692  * CLR_GRAY 		7	low-intensity white
693  * NO_COLOR		8
694  * CLR_ORANGE		9
695  * CLR_BRIGHT_GREEN 	10
696  * CLR_YELLOW		11
697  * CLR_BRIGHT_BLUE	12
698  * CLR_BRIGHT_MAGENTA	13
699  * CLR_BRIGHT_CYAN	14
700  * CLR_WHITE		15
701  * CLR_MAX		16
702  * BRIGHT		8
703  */
704 
705 #ifdef VIDEOSHADES
706 /* assign_videoshades() is prototyped in extern.h */
707 /* assign_videocolors() is prototyped in extern.h */
708 /* assign_video()	is prototyped in extern.h */
709 
710 int shadeflag; /* shades are initialized */
711 int colorflag; /* colors are initialized */
712 const char *schoice[3] = { "dark", "normal", "light" };
713 const char *shade[3];
714 #endif /* VIDEOSHADES */
715 
716 static void
init_ttycolor(void)717 init_ttycolor(void)
718 {
719 #ifdef VIDEOSHADES
720     if (!shadeflag) {
721         ttycolors[CLR_BLACK] = M_BLACK; /*  8 = dark gray */
722         ttycolors[CLR_WHITE] = M_WHITE; /* 15 = bright white */
723         ttycolors[CLR_GRAY] = M_GRAY;   /*  7 = normal white */
724         shade[0] = schoice[0];
725         shade[1] = schoice[1];
726         shade[2] = schoice[2];
727     }
728 #else
729     ttycolors[CLR_BLACK] = M_GRAY; /*  mapped to white */
730     ttycolors[CLR_WHITE] = M_GRAY; /*  mapped to white */
731     ttycolors[CLR_GRAY] = M_GRAY;  /*  mapped to white */
732 #endif
733 
734 #ifdef VIDEOSHADES
735     if (!colorflag) {
736 #endif
737         ttycolors[CLR_RED] = M_RED;
738         ttycolors[CLR_GREEN] = M_GREEN;
739         ttycolors[CLR_BROWN] = M_BROWN;
740         ttycolors[CLR_BLUE] = M_BLUE;
741         ttycolors[CLR_MAGENTA] = M_MAGENTA;
742         ttycolors[CLR_CYAN] = M_CYAN;
743         ttycolors[BRIGHT] = M_WHITE;
744         ttycolors[CLR_ORANGE] = M_ORANGE;
745         ttycolors[CLR_BRIGHT_GREEN] = M_BRIGHTGREEN;
746         ttycolors[CLR_YELLOW] = M_YELLOW;
747         ttycolors[CLR_BRIGHT_BLUE] = M_BRIGHTBLUE;
748         ttycolors[CLR_BRIGHT_MAGENTA] = M_BRIGHTMAGENTA;
749         ttycolors[CLR_BRIGHT_CYAN] = M_BRIGHTCYAN;
750 #ifdef VIDEOSHADES
751     }
752 #endif
753 }
754 
755 static int convert_uchars(char *, uchar *, int);
756 #ifdef VIDEOSHADES
757 int
assign_videoshades(char * choiceptr)758 assign_videoshades(char *choiceptr)
759 {
760     char choices[120];
761     char *cptr, *cvalue[3];
762     int i, icolor = CLR_WHITE;
763 
764     strcpy(choices, choiceptr);
765     cvalue[0] = choices;
766 
767     /* find the next ' ' or tab */
768     cptr = index(cvalue[0], '-');
769     if (!cptr)
770         cptr = index(cvalue[0], ' ');
771     if (!cptr)
772         cptr = index(cvalue[0], '\t');
773     if (!cptr)
774         return 0;
775     *cptr = '\0';
776     /* skip  whitespace between '=' and value */
777     do {
778         ++cptr;
779     } while (isspace(*cptr) || (*cptr == '-'));
780     cvalue[1] = cptr;
781 
782     cptr = index(cvalue[1], '-');
783     if (!cptr)
784         cptr = index(cvalue[0], ' ');
785     if (!cptr)
786         cptr = index(cvalue[0], '\t');
787     if (!cptr)
788         return 0;
789     *cptr = '\0';
790     do {
791         ++cptr;
792     } while (isspace(*cptr) || (*cptr == '-'));
793     cvalue[2] = cptr;
794 
795     for (i = 0; i < 3; ++i) {
796         switch (i) {
797         case 0:
798             icolor = CLR_BLACK;
799             break;
800         case 1:
801             icolor = CLR_GRAY;
802             break;
803         case 2:
804             icolor = CLR_WHITE;
805             break;
806         }
807 
808         shadeflag = 1;
809         if ((strncmpi(cvalue[i], "black", 5) == 0)
810             || (strncmpi(cvalue[i], "dark", 4) == 0)) {
811             shade[i] = schoice[0];
812             ttycolors[icolor] = M_BLACK; /* dark gray */
813         } else if ((strncmpi(cvalue[i], "gray", 4) == 0)
814                    || (strncmpi(cvalue[i], "grey", 4) == 0)
815                    || (strncmpi(cvalue[i], "medium", 6) == 0)
816                    || (strncmpi(cvalue[i], "normal", 6) == 0)) {
817             shade[i] = schoice[1];
818             ttycolors[icolor] = M_GRAY; /* regular gray */
819         } else if ((strncmpi(cvalue[i], "white", 5) == 0)
820                    || (strncmpi(cvalue[i], "light", 5) == 0)) {
821             shade[i] = schoice[2];
822             ttycolors[icolor] = M_WHITE; /* bright white */
823         } else {
824             shadeflag = 0;
825             return 0;
826         }
827     }
828     return 1;
829 }
830 
831 /*
832  * Process defaults.nh OPTIONS=videocolors:xxx
833  * Left to right assignments for:
834  *	red green brown blue magenta cyan orange br.green yellow
835  *	br.blue br.mag br.cyan
836  *
837  * Default Mapping (BIOS): 4-2-6-1-5-3-12-10-14-9-13-11
838  */
839 int
assign_videocolors(char * colorvals)840 assign_videocolors(char *colorvals)
841 {
842     int i, icolor;
843     uchar *tmpcolor;
844 
845     init_ttycolor(); /* in case defaults.nh entry wasn't complete */
846     i = strlen(colorvals);
847     tmpcolor = (uchar *) alloc(i);
848     (void) convert_uchars(colorvals, tmpcolor, i);
849     icolor = CLR_RED;
850     for (i = 0; tmpcolor[i] != 0; ++i) {
851         if (icolor < (CLR_WHITE)) {
852             ttycolors[icolor++] = tmpcolor[i];
853             if ((icolor > CLR_CYAN) && (icolor < CLR_ORANGE)) {
854                 icolor = CLR_ORANGE;
855             }
856         }
857     }
858     colorflag = 1;
859     free((genericptr_t) tmpcolor);
860     return 1;
861 }
862 
863 static int
convert_uchars(char * bufp,uchar * list,int size)864 convert_uchars(char *bufp,  /* current pointer */
865                uchar *list, /* return list */
866                int size)
867 {
868     unsigned int num = 0;
869     int count = 0;
870 
871     while (1) {
872         switch (*bufp) {
873         case ' ':
874         case '\0':
875         case '\t':
876         case '-':
877         case '\n':
878             if (num) {
879                 list[count++] = num;
880                 num = 0;
881             }
882             if ((count == size) || !*bufp)
883                 return count;
884             bufp++;
885             break;
886 
887         case '0':
888         case '1':
889         case '2':
890         case '3':
891         case '4':
892         case '5':
893         case '6':
894         case '7':
895         case '8':
896         case '9':
897             num = num * 10 + (*bufp - '0');
898             bufp++;
899             break;
900             return count;
901         }
902     }
903     /*NOTREACHED*/
904 }
905 
906 #endif /* VIDEOSHADES */
907 #endif /* TEXTCOLOR */
908 
909 /*
910  * Process defaults.nh OPTIONS=video:xxxx
911  *
912  *    where (current) legitimate values are:
913  *
914  *    autodetect (attempt to determine the adapter type)
915  *    default	 (force use of the default video method for environment)
916  *    vga	 (use vga adapter code)
917  */
918 int
assign_video(char * sopt)919 assign_video(char *sopt)
920 {
921     /*
922      * debug
923      *
924      *	printf("video is %s",sopt);
925      *	getch();
926      */
927     iflags.grmode = 0;
928     iflags.hasvesa = 0;
929     iflags.hasvga = 0;
930     iflags.usevesa = 0;
931     iflags.usevga = 0;
932 
933     if (strncmpi(sopt, "def", 3) == 0) { /* default */
934                                          /* do nothing - default */
935 #ifdef SCREEN_VGA
936     } else if (strncmpi(sopt, "vga", 3) == 0) { /* vga */
937         iflags.usevga = 1;
938         iflags.hasvga = 1;
939 #endif
940 #ifdef SCREEN_VESA
941     } else if (strncmpi(sopt, "vesa", 4) == 0) { /* vesa */
942         iflags.hasvesa = 1;
943         iflags.usevesa = 1;
944 #endif
945 #ifdef SCREEN_8514
946     } else if (strncmpi(sopt, "8514", 4) == 0) { /* 8514/A */
947         iflags.use8514 = 1;
948         iflags.has8514 = 1;
949 #endif
950     } else if (strncmpi(sopt, "auto", 4) == 0) { /* autodetect */
951 #ifdef SCREEN_VESA
952         if (vesa_detect()) {
953             iflags.hasvesa = 1;
954         }
955 #endif
956 #ifdef SCREEN_8514
957         if (v8514_detect()) {
958             iflags.has8514 = 1;
959         }
960 #endif
961 #ifdef SCREEN_VGA
962         if (vga_detect()) {
963             iflags.hasvga = 1;
964         }
965 #endif
966         /*
967          * Auto-detect Priorities (arbitrary for now):
968          *	VESA, VGA
969          */
970         if (iflags.hasvesa) iflags.usevesa = 1;
971         else if (iflags.hasvga) {
972             iflags.usevga = 1;
973             /* VGA depends on BIOS to enable function keys*/
974             iflags.BIOS = 1;
975             iflags.rawio = 1;
976         }
977     } else {
978         return 0;
979     }
980     return 1;
981 }
982 
983 void
tileview(boolean enable)984 tileview(boolean enable)
985 {
986 #ifdef SCREEN_VGA
987     if (iflags.grmode && iflags.usevga)
988         vga_traditional(enable ? FALSE : TRUE);
989 #endif
990 #ifdef SCREEN_VESA
991     if (iflags.grmode && iflags.usevesa)
992         vesa_traditional(enable ? FALSE : TRUE);
993 #endif
994 }
995 #endif /* NO_TERMS  */
996 
997 #else  /* STUBVIDEO */
998 
999 void
tileview(boolean enable)1000 tileview(boolean enable)
1001 {
1002 }
1003 #endif /* STUBVIDEO */
1004 
1005 /*video.c*/
1006