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