1 /* NetHack 3.6	video.c	$NHDT-Date: 1554215931 2019/04/02 14:38:51 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.12 $ */
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()76 get_scr_size()
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 FDECL(get_cursor, (int *, int *));
120 #endif
121 
122 void FDECL(adjust_cursor_flags, (struct WinDesc *));
123 void FDECL(cmov, (int, int));
124 void FDECL(nocmov, (int, int));
125 STATIC_DCL void NDECL(init_ttycolor);
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()142 backsp()
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()158 clear_screen()
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()173 void cl_end() /* 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()193 void cl_eos() /* 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(col,row)212 cmov(col, row)
213 register int col, row;
214 {
215     ttyDisplay->cury = (uchar) row;
216     ttyDisplay->curx = (uchar) col;
217     if (!iflags.grmode) {
218         txt_gotoxy(col, row);
219 #ifdef SCREEN_VGA
220     } else if (iflags.usevga) {
221         vga_gotoloc(col, row);
222 #endif
223 #ifdef SCREEN_VESA
224     } else if (iflags.usevesa) {
225         vesa_gotoloc(col, row);
226 #endif
227     }
228 }
229 
230 #if 0
231 int
232 has_color(int color)
233 {
234     ++color; /* prevents compiler warning (unref. param) */
235 #ifdef TEXTCOLOR
236     return (monoflag) ? 0 : 1;
237 #else
238     return 0;
239 #endif
240 }
241 #endif
242 
243 void
home()244 home()
245 {
246     tty_curs(BASE_WINDOW, 1, 0);
247     ttyDisplay->curx = ttyDisplay->cury = (uchar) 0;
248     if (!iflags.grmode) {
249         txt_gotoxy(0, 0);
250 #ifdef SCREEN_VGA
251     } else if (iflags.usevga) {
252         vga_gotoloc(0, 0);
253 #endif
254 #ifdef SCREEN_VESA
255     } else if (iflags.usevesa) {
256         vesa_gotoloc(0, 0);
257 #endif
258     }
259 }
260 
261 void
nocmov(col,row)262 nocmov(col, row)
263 int col, row;
264 {
265     if (!iflags.grmode) {
266         txt_gotoxy(col, row);
267 #ifdef SCREEN_VGA
268     } else if (iflags.usevga) {
269         vga_gotoloc(col, row);
270 #endif
271 #ifdef SCREEN_VESA
272     } else if (iflags.usevesa) {
273         vesa_gotoloc(col, row);
274 #endif
275     }
276 }
277 
278 void
standoutbeg()279 standoutbeg()
280 {
281     g_attribute = iflags.grmode ? attrib_gr_intense : attrib_text_intense;
282 }
283 
284 void
standoutend()285 standoutend()
286 {
287     g_attribute = iflags.grmode ? attrib_gr_normal : attrib_text_normal;
288 }
289 
290 int
term_attr_fixup(int attrmask)291 term_attr_fixup(int attrmask)
292 {
293     return attrmask;
294 }
295 
296 void
term_end_attr(int attr)297 term_end_attr(int attr)
298 {
299     switch (attr) {
300     case ATR_ULINE:
301     case ATR_BOLD:
302     case ATR_BLINK:
303     case ATR_INVERSE:
304     default:
305         g_attribute = iflags.grmode ? attrib_gr_normal : attrib_text_normal;
306     }
307 }
308 
309 void
term_end_color(void)310 term_end_color(void)
311 {
312     g_attribute = iflags.grmode ? attrib_gr_normal : attrib_text_normal;
313 }
314 
315 void
term_end_raw_bold(void)316 term_end_raw_bold(void)
317 {
318     standoutend();
319 }
320 
321 void
term_start_attr(int attr)322 term_start_attr(int attr)
323 {
324     switch (attr) {
325     case ATR_ULINE:
326         if (monoflag) {
327             g_attribute = ATTRIB_MONO_UNDERLINE;
328         } else {
329             g_attribute =
330                 iflags.grmode ? attrib_gr_intense : attrib_text_intense;
331         }
332         break;
333     case ATR_BOLD:
334         g_attribute = iflags.grmode ? attrib_gr_intense : attrib_text_intense;
335         break;
336     case ATR_BLINK:
337         if (monoflag) {
338             g_attribute = ATTRIB_MONO_BLINK;
339         } else {
340             g_attribute =
341                 iflags.grmode ? attrib_gr_intense : attrib_text_intense;
342         }
343         break;
344     case ATR_INVERSE:
345         if (monoflag) {
346             g_attribute = ATTRIB_MONO_REVERSE;
347         } else {
348             g_attribute =
349                 iflags.grmode ? attrib_gr_intense : attrib_text_intense;
350         }
351         break;
352     default:
353         g_attribute = iflags.grmode ? attrib_gr_normal : attrib_text_normal;
354         break;
355     }
356 }
357 
358 void
term_start_color(int color)359 term_start_color(int color)
360 {
361 #ifdef TEXTCOLOR
362     if (monoflag) {
363         g_attribute = attrib_text_normal;
364     } else {
365         if (color >= 0 && color < CLR_MAX) {
366             if (iflags.grmode)
367                 g_attribute = color;
368             else
369                 g_attribute = ttycolors[color];
370         }
371     }
372 #endif
373 }
374 
375 void
term_start_raw_bold(void)376 term_start_raw_bold(void)
377 {
378     standoutbeg();
379 }
380 
381 void
tty_delay_output()382 tty_delay_output()
383 {
384 #ifdef TIMED_DELAY
385     if (flags.nap) {
386         (void) fflush(stdout);
387         msleep(50); /* sleep for 50 milliseconds */
388         return;
389     }
390 #endif
391 }
392 
393 void
tty_end_screen()394 tty_end_screen()
395 {
396     if (!iflags.grmode) {
397         txt_clear_screen();
398 #ifdef PC9800
399         fputs("\033[>1l", stdout);
400 #endif
401 #ifdef SCREEN_VGA
402     } else if (iflags.usevga) {
403         vga_tty_end_screen();
404 #endif
405 #ifdef SCREEN_VESA
406     } else if (iflags.usevesa) {
407         vesa_tty_end_screen();
408 #endif
409     }
410 }
411 
412 void
tty_nhbell()413 tty_nhbell()
414 {
415     txt_nhbell();
416 }
417 
418 void
tty_number_pad(state)419 tty_number_pad(state)
420 int state;
421 {
422     ++state; /* prevents compiler warning (unref. param) */
423 }
424 
425 void
tty_startup(wid,hgt)426 tty_startup(wid, hgt)
427 int *wid, *hgt;
428 {
429     /* code to sense display adapter is required here - MJA */
430 
431     attrib_text_normal = ATTRIB_NORMAL;
432     attrib_text_intense = ATTRIB_INTENSE;
433 
434     /* These are defaults and may get overridden */
435     attrib_gr_normal = attrib_text_normal;
436     attrib_gr_intense = attrib_text_intense;
437     g_attribute = attrib_text_normal; /* Give it a starting value */
438 
439 #ifdef SCREEN_VGA
440     if (iflags.usevga) {
441         vga_tty_startup(wid, hgt);
442     } else
443 #endif
444 #ifdef SCREEN_VESA
445     if (iflags.usevesa) {
446         vesa_tty_startup(wid, hgt);
447     } else
448 #endif
449         txt_startup(wid, hgt);
450 
451     *wid = CO;
452     *hgt = LI;
453 
454 #ifdef CLIPPING
455     if (CO < COLNO || LI < ROWNO + 3)
456         setclipped();
457 #endif
458 
459 #ifdef TEXTCOLOR
460     init_ttycolor();
461 #endif
462 
463 #ifdef MONO_CHECK
464     monoflag = txt_monoadapt_check();
465 #else
466     monoflag = 0;
467 #endif
468 }
469 
470 void
tty_start_screen()471 tty_start_screen()
472 {
473 #ifdef PC9800
474     fputs("\033[>1h", stdout);
475 #endif
476     if (iflags.num_pad)
477         tty_number_pad(1); /* make keypad send digits */
478 }
479 
480 void
gr_init()481 gr_init()
482 {
483 #ifdef SCREEN_VGA
484     if (iflags.usevga) {
485         vga_Init();
486     } else
487 #endif
488 #ifdef SCREEN_VESA
489     if (iflags.usevesa) {
490         vesa_Init();
491     } else
492 #endif
493 #ifdef SCREEN_8514
494     if (iflags.use8514) {
495         v8514_Init();
496     } else
497 #endif
498     {}
499 }
500 
501 void
gr_finish()502 gr_finish()
503 {
504     if (iflags.grmode) {
505 #ifdef SCREEN_VGA
506         if (iflags.usevga) {
507             vga_Finish();
508         } else
509 #endif
510 #ifdef SCREEN_VESA
511         if (iflags.usevesa) {
512             vesa_Finish();
513         } else
514 #endif
515 #ifdef SCREEN_8514
516         if (iflags.use8514) {
517             v8514_Finish();
518         } else
519 #endif
520         {}
521     }
522 }
523 
524 /*
525  * Screen output routines (these are heavily used).
526  *
527  * These are the 3 routines used to place information on the screen
528  * in the NO_TERMS PC tty port of NetHack.  These are the routines
529  * that get called by routines in other NetHack source files (such
530  * as those in win/tty).
531  *
532  * xputs - Writes a c null terminated string at the current location.
533  *	   Depending on compile options, this could just be a series
534  *	   of repeated calls to xputc() for each character.
535  *
536  * xputc - Writes a single character at the current location. Since
537  *	   various places in the code assume that control characters
538  *	   can be used to control, we are forced to interpret some of
539  *	   the more common ones, in order to keep things looking correct.
540  *
541  * xputg - If using a graphics mode display mechanism (such as VGA, this
542  *	   routine is used to display a graphical representation of a
543  *	   NetHack glyph at the current location.  For more information on
544  *	   NetHack glyphs refer to the comments in include/display.h.
545  *
546  * NOTES:
547  *	   wintty.h uses macros to redefine common output functions
548  *	   such as puts, putc, putchar, so that they get steered into
549  *	   either xputs (for strings) or xputc (for single characters).
550  *	   References to puts, putc, and putchar in other source files
551  *	   (that include wintty.h) are actually using these routines.
552  */
553 
554 void
xputs(s)555 xputs(s)
556 const char *s;
557 {
558     int col, row;
559 
560     col = (int) ttyDisplay->curx;
561     row = (int) ttyDisplay->cury;
562 
563     if (!iflags.grmode) {
564         txt_xputs(s, col, row);
565 #ifdef SCREEN_VGA
566     } else if (iflags.usevga) {
567         vga_xputs(s, col, row);
568 #endif
569 #ifdef SCREEN_VESA
570     } else if (iflags.usevesa) {
571         vesa_xputs(s, col, row);
572 #endif
573     }
574 }
575 
576 /* same signature as 'putchar()' with potential failure result ignored */
577 int
xputc(ch)578 xputc(ch) /* write out character (and attribute) */
579 int ch;
580 {
581     int i;
582     char attribute;
583 
584     i = iflags.grmode ? attrib_gr_normal : attrib_text_normal;
585 
586     attribute = (char) ((g_attribute == 0) ? i : g_attribute);
587     if (!iflags.grmode) {
588         txt_xputc(ch, attribute);
589 #ifdef SCREEN_VGA
590     } else if (iflags.usevga) {
591         vga_xputc(ch, attribute);
592 #endif /*SCREEN_VGA*/
593 #ifdef SCREEN_VESA
594     } else if (iflags.usevesa) {
595         vesa_xputc(ch, attribute);
596 #endif /*SCREEN_VESA*/
597     }
598     return 0;
599 }
600 
601 /* write out a glyph picture at current location */
xputg(glyphnum,ch,special)602 void xputg(glyphnum, ch, special)
603 int glyphnum;
604 int ch;
605 unsigned special;
606 {
607     if (!iflags.grmode || !iflags.tile_view) {
608         (void) xputc((char) ch);
609 #ifdef SCREEN_VGA
610     } else if (iflags.grmode && iflags.usevga) {
611         vga_xputg(glyphnum, ch, special);
612 #endif
613 #ifdef SCREEN_VESA
614     } else if (iflags.grmode && iflags.usevesa) {
615         vesa_xputg(glyphnum, ch, special);
616 #endif
617     }
618 }
619 
620 #ifdef POSITIONBAR
621 void
video_update_positionbar(posbar)622 video_update_positionbar(posbar)
623 char *posbar;
624 {
625     if (!iflags.grmode)
626         return;
627 #ifdef SCREEN_VGA
628     else if (iflags.usevga)
629         vga_update_positionbar(posbar);
630 #endif
631 #ifdef SCREEN_VESA
632     else if (iflags.usevesa)
633         vesa_update_positionbar(posbar);
634 #endif
635 }
636 #endif
637 
638 void
adjust_cursor_flags(cw)639 adjust_cursor_flags(cw)
640 struct WinDesc *cw;
641 {
642 #ifdef SIMULATE_CURSOR
643 #if 0
644     if (cw->type == NHW_MAP) cursor_flag = 1;
645     else cursor_flag = 0;
646 #else
647     if (cw->type == NHW_MAP) {
648         inmap = 1;
649         cursor_flag = 1;
650     } else {
651         inmap = 0;
652         cursor_flag = 1;
653     }
654 #endif /* 0 */
655 #endif /* SIMULATE_CURSOR */
656 }
657 
658 #ifdef SIMULATE_CURSOR
659 
660 /* change the defaults in pcvideo.h, not here */
661 int cursor_type = CURSOR_DEFAULT_STYLE;
662 int cursor_color = CURSOR_DEFAULT_COLOR;
663 int cursor_flag;
664 
665 /* The check for iflags.grmode is made BEFORE calling these. */
666 void
DrawCursor()667 DrawCursor()
668 {
669 #ifdef SCREEN_VGA
670     if (iflags.usevga)
671         vga_DrawCursor();
672 #endif
673 #ifdef SCREEN_VESA
674     if (iflags.usevesa)
675         vesa_DrawCursor();
676 #endif
677 }
678 
679 void
HideCursor()680 HideCursor()
681 {
682 #ifdef SCREEN_VGA
683     if (iflags.usevga)
684         vga_HideCursor();
685 #endif
686 #ifdef SCREEN_VESA
687     if (iflags.usevesa)
688         vesa_HideCursor();
689 #endif
690 }
691 
692 #endif /* SIMULATE_CURSOR */
693 
694 #ifdef TEXTCOLOR
695 /*
696  * CLR_BLACK		0
697  * CLR_RED		1
698  * CLR_GREEN		2
699  * CLR_BROWN		3	low-intensity yellow
700  * CLR_BLUE 		4
701  * CLR_MAGENTA		5
702  * CLR_CYAN 		6
703  * CLR_GRAY 		7	low-intensity white
704  * NO_COLOR		8
705  * CLR_ORANGE		9
706  * CLR_BRIGHT_GREEN 	10
707  * CLR_YELLOW		11
708  * CLR_BRIGHT_BLUE	12
709  * CLR_BRIGHT_MAGENTA	13
710  * CLR_BRIGHT_CYAN	14
711  * CLR_WHITE		15
712  * CLR_MAX		16
713  * BRIGHT		8
714  */
715 
716 #ifdef VIDEOSHADES
717 /* assign_videoshades() is prototyped in extern.h */
718 /* assign_videocolors() is prototyped in extern.h */
719 /* assign_video()	is prototyped in extern.h */
720 
721 int shadeflag; /* shades are initialized */
722 int colorflag; /* colors are initialized */
723 char *schoice[3] = { "dark", "normal", "light" };
724 char *shade[3];
725 #endif /* VIDEOSHADES */
726 
727 STATIC_OVL void
init_ttycolor()728 init_ttycolor()
729 {
730 #ifdef VIDEOSHADES
731     if (!shadeflag) {
732         ttycolors[CLR_BLACK] = M_BLACK; /*  8 = dark gray */
733         ttycolors[CLR_WHITE] = M_WHITE; /* 15 = bright white */
734         ttycolors[CLR_GRAY] = M_GRAY;   /*  7 = normal white */
735         shade[0] = schoice[0];
736         shade[1] = schoice[1];
737         shade[2] = schoice[2];
738     }
739 #else
740     ttycolors[CLR_BLACK] = M_GRAY; /*  mapped to white */
741     ttycolors[CLR_WHITE] = M_GRAY; /*  mapped to white */
742     ttycolors[CLR_GRAY] = M_GRAY;  /*  mapped to white */
743 #endif
744 
745 #ifdef VIDEOSHADES
746     if (!colorflag) {
747 #endif
748         ttycolors[CLR_RED] = M_RED;
749         ttycolors[CLR_GREEN] = M_GREEN;
750         ttycolors[CLR_BROWN] = M_BROWN;
751         ttycolors[CLR_BLUE] = M_BLUE;
752         ttycolors[CLR_MAGENTA] = M_MAGENTA;
753         ttycolors[CLR_CYAN] = M_CYAN;
754         ttycolors[BRIGHT] = M_WHITE;
755         ttycolors[CLR_ORANGE] = M_ORANGE;
756         ttycolors[CLR_BRIGHT_GREEN] = M_BRIGHTGREEN;
757         ttycolors[CLR_YELLOW] = M_YELLOW;
758         ttycolors[CLR_BRIGHT_BLUE] = M_BRIGHTBLUE;
759         ttycolors[CLR_BRIGHT_MAGENTA] = M_BRIGHTMAGENTA;
760         ttycolors[CLR_BRIGHT_CYAN] = M_BRIGHTCYAN;
761 #ifdef VIDEOSHADES
762     }
763 #endif
764 }
765 
766 static int FDECL(convert_uchars, (char *, uchar *, int));
767 #ifdef VIDEOSHADES
768 int
assign_videoshades(char * choiceptr)769 assign_videoshades(char *choiceptr)
770 {
771     char choices[120];
772     char *cptr, *cvalue[3];
773     int i, icolor = CLR_WHITE;
774 
775     strcpy(choices, choiceptr);
776     cvalue[0] = choices;
777 
778     /* find the next ' ' or tab */
779     cptr = index(cvalue[0], '-');
780     if (!cptr)
781         cptr = index(cvalue[0], ' ');
782     if (!cptr)
783         cptr = index(cvalue[0], '\t');
784     if (!cptr)
785         return 0;
786     *cptr = '\0';
787     /* skip  whitespace between '=' and value */
788     do {
789         ++cptr;
790     } while (isspace(*cptr) || (*cptr == '-'));
791     cvalue[1] = cptr;
792 
793     cptr = index(cvalue[1], '-');
794     if (!cptr)
795         cptr = index(cvalue[0], ' ');
796     if (!cptr)
797         cptr = index(cvalue[0], '\t');
798     if (!cptr)
799         return 0;
800     *cptr = '\0';
801     do {
802         ++cptr;
803     } while (isspace(*cptr) || (*cptr == '-'));
804     cvalue[2] = cptr;
805 
806     for (i = 0; i < 3; ++i) {
807         switch (i) {
808         case 0:
809             icolor = CLR_BLACK;
810             break;
811         case 1:
812             icolor = CLR_GRAY;
813             break;
814         case 2:
815             icolor = CLR_WHITE;
816             break;
817         }
818 
819         shadeflag = 1;
820         if ((strncmpi(cvalue[i], "black", 5) == 0)
821             || (strncmpi(cvalue[i], "dark", 4) == 0)) {
822             shade[i] = schoice[0];
823             ttycolors[icolor] = M_BLACK; /* dark gray */
824         } else if ((strncmpi(cvalue[i], "gray", 4) == 0)
825                    || (strncmpi(cvalue[i], "grey", 4) == 0)
826                    || (strncmpi(cvalue[i], "medium", 6) == 0)
827                    || (strncmpi(cvalue[i], "normal", 6) == 0)) {
828             shade[i] = schoice[1];
829             ttycolors[icolor] = M_GRAY; /* regular gray */
830         } else if ((strncmpi(cvalue[i], "white", 5) == 0)
831                    || (strncmpi(cvalue[i], "light", 5) == 0)) {
832             shade[i] = schoice[2];
833             ttycolors[icolor] = M_WHITE; /* bright white */
834         } else {
835             shadeflag = 0;
836             return 0;
837         }
838     }
839     return 1;
840 }
841 
842 /*
843  * Process defaults.nh OPTIONS=videocolors:xxx
844  * Left to right assignments for:
845  *	red green brown blue magenta cyan orange br.green yellow
846  *	br.blue br.mag br.cyan
847  *
848  * Default Mapping (BIOS): 4-2-6-1-5-3-12-10-14-9-13-11
849  */
850 int
assign_videocolors(char * colorvals)851 assign_videocolors(char *colorvals)
852 {
853     int i, icolor;
854     uchar *tmpcolor;
855 
856     init_ttycolor(); /* in case defaults.nh entry wasn't complete */
857     i = strlen(colorvals);
858     tmpcolor = (uchar *) alloc(i);
859     (void) convert_uchars(colorvals, tmpcolor, i);
860     icolor = CLR_RED;
861     for (i = 0; tmpcolor[i] != 0; ++i) {
862         if (icolor < (CLR_WHITE)) {
863             ttycolors[icolor++] = tmpcolor[i];
864             if ((icolor > CLR_CYAN) && (icolor < CLR_ORANGE)) {
865                 icolor = CLR_ORANGE;
866             }
867         }
868     }
869     colorflag = 1;
870     free((genericptr_t) tmpcolor);
871     return 1;
872 }
873 
874 static int
convert_uchars(bufp,list,size)875 convert_uchars(bufp, list, size)
876 char *bufp;  /* current pointer */
877 uchar *list; /* return list */
878 int size;
879 {
880     unsigned int num = 0;
881     int count = 0;
882 
883     while (1) {
884         switch (*bufp) {
885         case ' ':
886         case '\0':
887         case '\t':
888         case '-':
889         case '\n':
890             if (num) {
891                 list[count++] = num;
892                 num = 0;
893             }
894             if ((count == size) || !*bufp)
895                 return count;
896             bufp++;
897             break;
898 
899         case '0':
900         case '1':
901         case '2':
902         case '3':
903         case '4':
904         case '5':
905         case '6':
906         case '7':
907         case '8':
908         case '9':
909             num = num * 10 + (*bufp - '0');
910             bufp++;
911             break;
912             return count;
913         }
914     }
915     /*NOTREACHED*/
916 }
917 
918 #endif /* VIDEOSHADES */
919 #endif /* TEXTCOLOR */
920 
921 /*
922  * Process defaults.nh OPTIONS=video:xxxx
923  *
924  *    where (current) legitimate values are:
925  *
926  *    autodetect (attempt to determine the adapter type)
927  *    default	 (force use of the default video method for environment)
928  *    vga	 (use vga adapter code)
929  */
930 int
assign_video(sopt)931 assign_video(sopt)
932 char *sopt;
933 {
934     /*
935      * debug
936      *
937      *	printf("video is %s",sopt);
938      *	getch();
939      */
940     iflags.grmode = 0;
941     iflags.hasvesa = 0;
942     iflags.hasvga = 0;
943     iflags.usevesa = 0;
944     iflags.usevga = 0;
945 
946     if (strncmpi(sopt, "def", 3) == 0) { /* default */
947                                          /* do nothing - default */
948 #ifdef SCREEN_VGA
949     } else if (strncmpi(sopt, "vga", 3) == 0) { /* vga */
950         iflags.usevga = 1;
951         iflags.hasvga = 1;
952 #endif
953 #ifdef SCREEN_VESA
954     } else if (strncmpi(sopt, "vesa", 4) == 0) { /* vesa */
955         iflags.hasvesa = 1;
956         iflags.usevesa = 1;
957 #endif
958 #ifdef SCREEN_8514
959     } else if (strncmpi(sopt, "8514", 4) == 0) { /* 8514/A */
960         iflags.use8514 = 1;
961         iflags.has8514 = 1;
962 #endif
963     } else if (strncmpi(sopt, "auto", 4) == 0) { /* autodetect */
964 #ifdef SCREEN_VESA
965         if (vesa_detect()) {
966             iflags.hasvesa = 1;
967         }
968 #endif
969 #ifdef SCREEN_8514
970         if (v8514_detect()) {
971             iflags.has8514 = 1;
972         }
973 #endif
974 #ifdef SCREEN_VGA
975         if (vga_detect()) {
976             iflags.hasvga = 1;
977         }
978 #endif
979         /*
980          * Auto-detect Priorities (arbitrary for now):
981          *	VESA, VGA
982          */
983         if (iflags.hasvesa) iflags.usevesa = 1;
984         else if (iflags.hasvga) {
985             iflags.usevga = 1;
986             /* VGA depends on BIOS to enable function keys*/
987             iflags.BIOS = 1;
988             iflags.rawio = 1;
989         }
990     } else {
991         return 0;
992     }
993     return 1;
994 }
995 
996 void
tileview(enable)997 tileview(enable)
998 boolean enable;
999 {
1000 #ifdef SCREEN_VGA
1001     if (iflags.grmode && iflags.usevga)
1002         vga_traditional(enable ? FALSE : TRUE);
1003 #endif
1004 #ifdef SCREEN_VESA
1005     if (iflags.grmode && iflags.usevesa)
1006         vesa_traditional(enable ? FALSE : TRUE);
1007 #endif
1008 }
1009 #endif /* NO_TERMS  */
1010 
1011 #else  /* STUBVIDEO */
1012 
1013 void
tileview(enable)1014 tileview(enable)
1015 boolean enable;
1016 {
1017 }
1018 #endif /* STUBVIDEO */
1019 
1020 /*video.c*/
1021