1 /* Copyright (c) 1992, 1995 John E. Davis
4 * You may distribute under the terms of either the GNU General Public
5 * License or the Perl Artistic License.
28 #if defined (__WATCOMC__)
30 # define int86 int386 /* simplify code writing */
33 #if defined (__GO32__)
38 #if defined (__os2__) && !defined (EMX_VIDEO)
45 # if defined (__EMX__) /* EMX video does both DOS & OS/2 */
49 # include <sys/video.h>
57 # define HAS_SAVE_SCREEN
60 /* ------------------------- global variables ------------------------- */
63 extern HANDLE hStdout
, hStdin
;
64 extern CONSOLE_SCREEN_BUFFER_INFO csbiInfo
;
68 int SLtt_Term_Cannot_Insert
;
69 int SLtt_Term_Cannot_Scroll
;
70 int SLtt_Ignore_Beep
= 3;
71 int SLtt_Use_Ansi_Colors
;
73 int SLtt_Screen_Rows
= 25;
74 int SLtt_Screen_Cols
= 80;
76 /* ------------------------- local variables -------------------------- */
77 static int Attribute_Byte
;
78 static int Scroll_r1
= 0, Scroll_r2
= 25;
79 static int Cursor_Row
= 1, Cursor_Col
= 1;
80 static int Current_Color
;
81 static int IsColor
= 1;
82 static int Blink_Killed
; /* high intensity background enabled */
84 #define JMAX_COLORS 256
85 #define JNORMAL_COLOR 0
88 static unsigned char Color_Map
[JMAX_COLORS
] =
90 0x7, 0x70, 0x70, 0x70, 0x70, 0x7, 0x7, 0x7,
91 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
92 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
93 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
94 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
95 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
96 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
97 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
98 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
99 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
100 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
101 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
102 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
103 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
104 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
105 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
106 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
107 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
108 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
109 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
110 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
111 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
112 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
113 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
114 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
115 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
116 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
117 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
118 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
119 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
120 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
121 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7
125 #define JMAX_COLOR_NAMES 16
126 static char *Color_Names
[JMAX_COLOR_NAMES
] =
128 "black", "blue", "green", "cyan",
129 "red", "magenta", "brown", "lightgray",
130 "gray", "brightblue", "brightgreen", "brightcyan",
131 "brightred", "brightmagenta", "yellow", "white"
135 * set_color_from_attribute (int attribute);
136 * define the correspondence of color to attribute
138 #define set_color_from_attribute(a)\
140 JNORMAL_COLOR, NULL,\
141 Color_Names[(a) & 0xf],\
142 Color_Names[(a) >> 4])
143 /* this is how to make a space character */
144 #define mkSpaceChar() (((Attribute_Byte) << 8) | 0x20)
146 /* buffer to hold a line of character/attribute pairs */
148 static unsigned char Line_Buffer
[MAXCOLS
*2];
150 /*----------------------------------------------------------------------*\
151 * define various ways and means of writing to the screen
152 \*----------------------------------------------------------------------*/
153 #if defined (__GO32__) || defined (__WATCOMC__)
154 # if !defined (GO32_VIDEO)
155 # define HAS_LINEAR_SCREEN
157 #else /* __GO32__ or __WATCOMC__ */
161 #endif /* __GO32__ or __WATCOMC__ */
163 /* define for direct to memory screen writes */
164 #if defined (USE_ASM) || defined (HAS_LINEAR_SCREEN)
165 static unsigned char *Video_Base
;
166 # define mkScreenPointer(row,col) ((unsigned short *)\
168 2 * (SLtt_Screen_Cols * (row)\
170 # if defined (USE_ASM)
171 int SLtt_Msdos_Cheap_Video
= 0;
172 static int Video_Status_Port
;
174 # define MONO_STATUS 0x3BA
175 # define CGA_STATUS 0x3DA
176 # define CGA_SETMODE 0x3D8
178 # define SNOW_CHECK \
179 if (SLtt_Msdos_Cheap_Video)\
180 { while ((inp (CGA_STATUS) & 0x08)); while (!(inp (CGA_STATUS) & 0x08)); }
181 # endif /* USE_ASM */
182 #endif /* USE_ASM or HAS_LINEAR_SCREEN */
185 /* -------------------------------------------------------------------- */
186 #if defined (__WATCOMC__)
187 # define ScreenPrimary (0xb800 << 4)
188 # define ScreenSize (SLtt_Screen_Cols * SLtt_Screen_Rows)
189 # define ScreenSetCursor (x,y) _settextposition (x+1,y+1)
190 void ScreenGetCursor (int *x
, int *y
)
192 struct rccoord rc
= _gettextposition ();
196 void ScreenRetrieve (unsigned char *dest
)
198 memcpy (dest
, (unsigned char *) ScreenPrimary
, 2 * ScreenSize
);
200 void ScreenUpdate (unsigned char *src
)
202 memcpy ((unsigned char *) ScreenPrimary
, src
, 2 * ScreenSize
);
204 #endif /* __WATCOMC__ */
206 #ifdef HAS_SAVE_SCREEN
207 static void *Saved_Screen_Buffer
;
208 static int Saved_Cursor_Row
;
210 static void save_screen (void)
214 if (Saved_Screen_Buffer
!= NULL
)
216 SLFREE (Saved_Screen_Buffer
);
217 Saved_Screen_Buffer
= NULL
;
220 Saved_Screen_Buffer
= SLMALLOC (sizeof (short) *
221 ScreenCols () * ScreenRows ());
223 if (Saved_Screen_Buffer
== NULL
)
226 ScreenRetrieve (Saved_Screen_Buffer
);
227 ScreenGetCursor (&row
, &col
);
228 Saved_Cursor_Row
= row
;
233 static void restore_screen (void)
235 if (Saved_Screen_Buffer
== NULL
) return;
237 ScreenUpdate (Saved_Screen_Buffer
);
238 SLtt_goto_rc (Saved_Cursor_Row
, 0);
242 #endif /* HAS_SAVE_SCREEN */
243 /*----------------------------------------------------------------------*\
244 * Function: void SLtt_write_string (char *str);
246 * put string STR to 'stdout'
247 \*----------------------------------------------------------------------*/
248 void SLtt_write_string (char *str
)
253 (void) WriteConsole(hStdout
, str
, strlen(str
), &bytes
, NULL
);
259 /*----------------------------------------------------------------------*\
260 * Function: void SLtt_set_scroll_region (int r1, int r2);
262 * define a scroll region of top_row to bottom_row
263 \*----------------------------------------------------------------------*/
264 void SLtt_set_scroll_region (int top_row
, int bottom_row
)
267 Scroll_r2
= bottom_row
;
270 /*----------------------------------------------------------------------*\
271 * Function: void SLtt_reset_scroll_region (void);
273 * reset the scrol region to be the entire screen,
274 * ie, SLtt_set_scroll_region (0, SLtt_Screen_Rows);
275 \*----------------------------------------------------------------------*/
276 void SLtt_reset_scroll_region (void)
279 Scroll_r2
= SLtt_Screen_Rows
;
282 /*----------------------------------------------------------------------*\
283 * Function: void SLtt_goto_rc (int row, int col);
285 * move the terminal cursor to x,y position COL, ROW and record the
286 * position in Cursor_Row, Cursor_Col
287 \*----------------------------------------------------------------------*/
288 void SLtt_goto_rc (int row
, int col
)
296 #if !defined (USE_ASM)
297 if (row
> SLtt_Screen_Rows
) row
= SLtt_Screen_Rows
;
298 if (col
> SLtt_Screen_Cols
) col
= SLtt_Screen_Cols
;
299 # if defined (EMX_VIDEO)
300 v_gotoxy (col
, Scroll_r1
+ row
);
301 # else /* EMX_VIDEO_ */
302 # if defined (__os2__)
303 VioSetCurPos (Scroll_r1
+ row
, col
, 0);
304 # elif defined(WIN32)
305 (void) SetConsoleCursorPosition(hStdout
, newPosition
);
307 # if defined (__GO32__) || defined (__WATCOMC__)
308 ScreenSetCursor(Scroll_r1
+ row
, col
);
309 # endif /* __GO32__ or __WATCOMC__ */
310 # endif /* __os2__ */
311 # endif /* EMX_VIDEO_ */
315 /* if (r > SLtt_Screen_Rows - 1) r = SLtt_Screen_Rows - 1; */
317 asm mov bx
, SLtt_Screen_Rows
323 /* if (c > SLtt_Screen_Cols - 1) c = SLtt_Screen_Cols - 1; */
324 asm mov cx
, SLtt_Screen_Cols
331 asm mov Cursor_Row
, ax
332 asm mov Cursor_Col
, bx
333 asm add ax
, Scroll_r1
343 /*----------------------------------------------------------------------*\
344 * Function: static void slvid_getxy (void);
346 * retrieve the cursor position into Cursor_Row, Cursor_Col
347 \*----------------------------------------------------------------------*/
348 static void slvid_getxy (void)
350 #if !defined (USE_ASM)
351 # if defined (EMX_VIDEO)
352 v_getxy (&Cursor_Col
, &Cursor_Row
);
353 # else /* EMX_VIDEO */
354 # if defined (__os2__)
355 VioGetCurPos ((USHORT
*) &Cursor_Row
, (USHORT
*) &Cursor_Col
, 0);
356 # elif defined(WIN32)
357 CONSOLE_SCREEN_BUFFER_INFO screenInfo
;
358 if (GetConsoleScreenBufferInfo(hStdout
, &screenInfo
) == TRUE
)
360 Cursor_Row
= screenInfo
.dwCursorPosition
.Y
;
361 Cursor_Col
= screenInfo
.dwCursorPosition
.X
;
364 # if defined (__GO32__) || defined (__WATCOMC__)
365 ScreenGetCursor (&Cursor_Row
, &Cursor_Col
);
366 # endif /* __GO32__ or __WATCOMC__ */
367 # endif /* __os2__ */
368 # endif /* EMX_VIDEO */
375 asm mov Cursor_Row
, ax
378 asm mov Cursor_Col
, ax
382 /*----------------------------------------------------------------------*\
383 * static void slvid_deleol (int x);
385 * write space characters from column X of row Cursor_Row through to
386 * SLtt_Screen_Cols using the current Attribute_Byte
387 \*----------------------------------------------------------------------*/
388 #if defined (GO32_VIDEO)
389 static void slvid_deleol (int x
)
391 while (x
< SLtt_Screen_Cols
)
392 ScreenPutChar (32, Attribute_Byte
, x
++, Cursor_Row
);
395 #if defined (EMX_VIDEO)
396 static void slvid_deleol (int x
)
398 unsigned char *p
, *pmax
;
399 int w
= mkSpaceChar ();
400 int count
= SLtt_Screen_Cols
- x
;
403 pmax
= p
+ 2 * count
;
407 *p
++ = (unsigned char) w
;
408 *p
++ = (unsigned char) (w
>> 8);
411 v_putline (Line_Buffer
, x
, Cursor_Row
, count
);
413 #endif /* EMX_VIDEO */
415 /*----------------------------------------------------------------------*\
416 * Function: void SLtt_begin_insert (void);
418 * insert a single space, moving everything right 1 character to make room
419 \*----------------------------------------------------------------------*/
420 void SLtt_begin_insert (void)
422 #if !defined (GO32_VIDEO)
423 # if defined (HAS_LINEAR_SCREEN) || defined (USE_ASM)
425 # if defined (HAS_LINEAR_SCREEN)
426 unsigned short *pmin
;
431 n
= SLtt_Screen_Cols
- Cursor_Col
;
432 /* Msdos_Insert_Mode = 1; */
435 # if defined (EMX_VIDEO)
436 v_getline (Line_Buffer
, Cursor_Col
, Cursor_Row
, n
);
437 v_putline (Line_Buffer
, Cursor_Col
+1, Cursor_Row
, n
- 1);
438 # else /* EMX_VIDEO */
439 # if defined (__os2__)
441 VioReadCellStr ((PCH
)Line_Buffer
, (USHORT
*) &n
, Cursor_Row
, Cursor_Col
, 0);
442 VioWrtCellStr ((PCH
)Line_Buffer
, n
, Cursor_Row
, Cursor_Col
+ 1, 0);
444 p
= mkScreenPointer (Cursor_Row
, SLtt_Screen_Cols
- 1);
446 # if defined (HAS_LINEAR_SCREEN)
447 /* pmin = p - (n-1); */
448 pmin
= mkScreenPointer (Cursor_Row
, Cursor_Col
);
449 while (p
-- > pmin
) *(p
+ 1) = *p
;
466 # endif /* HAS_LINEAR_SCREEN */
467 # endif /* __os2__ */
468 # endif /* EMX_VIDEO */
472 #endif /* not GO32_VIDEO */
475 /*----------------------------------------------------------------------*\
476 * Function: void SLtt_end_insert (void);
478 * any cleanup after insert a blank column
479 \*----------------------------------------------------------------------*/
480 void SLtt_end_insert (void)
484 /*----------------------------------------------------------------------*\
485 * Function: void SLtt_delete_char (void);
487 * delete a single character, moving everything left 1 column to take
489 \*----------------------------------------------------------------------*/
490 void SLtt_delete_char (void)
492 #if !defined (GO32_VIDEO)
493 # if defined (HAS_LINEAR_SCREEN) || defined (USE_ASM)
495 # if defined (HAS_LINEAR_SCREEN)
496 register unsigned short *p1
;
502 n
= SLtt_Screen_Cols
- Cursor_Col
- 1;
506 # if defined (EMX_VIDEO)
507 v_getline (Line_Buffer
, Cursor_Col
+1, Cursor_Row
, n
);
508 v_putline (Line_Buffer
, Cursor_Col
, Cursor_Row
, n
);
509 # else /* EMX_VIDEO */
510 # if defined (__os2__)
512 VioReadCellStr ((PCH
)Line_Buffer
, (USHORT
*)&n
, Cursor_Row
, Cursor_Col
+ 1, 0);
513 VioWrtCellStr ((PCH
)Line_Buffer
, n
, Cursor_Row
, Cursor_Col
, 0);
516 p
= mkScreenPointer (Cursor_Row
, Cursor_Col
);
518 # if defined (HAS_LINEAR_SCREEN)
525 # else /* HAS_LINEAR_SCREEN */
541 # endif /* HAS_LINEAR_SCREEN */
542 # endif /* __os2__ */
543 # endif /* EMX_VIDEO */
547 #endif /* not GO32_VIDEO */
550 /*----------------------------------------------------------------------*\
551 * Function: void SLtt_erase_line (void);
553 * This function is *only* called on exit.
554 * It sets attribute byte to Black & White
555 \*----------------------------------------------------------------------*/
556 void SLtt_erase_line (void)
561 # if defined (GO32_VIDEO) || defined (EMX_VIDEO)
562 Attribute_Byte
= 0x07;
564 # else /* GO32_VIDEO or EMX_VIDEO */
565 # if defined (__os2__)
567 Attribute_Byte
= 0x07;
569 VioWrtNCell ((BYTE
*)&w
, SLtt_Screen_Cols
, Cursor_Row
, 0, 0);
572 unsigned short *p
= mkScreenPointer (Cursor_Row
, 0);
573 # if defined (HAS_LINEAR_SCREEN)
574 register unsigned short *pmax
= p
+ SLtt_Screen_Cols
;
576 Attribute_Byte
= 0x07;
578 while (p
< pmax
) *p
++ = w
;
579 # else /* HAS_LINEAR_SCREEN */
580 Attribute_Byte
= 0x07;
585 asm mov cx
, SLtt_Screen_Cols
590 # endif /* HAS_LINEAR_SCREEN */
591 # endif /* __os2__ */
592 # endif /* GO32_VIDEO or EMX_VIDEO */
593 Current_Color
= JNO_COLOR
; /* since we messed with attribute byte */
599 /*----------------------------------------------------------------------*\
600 * Function: void SLtt_delete_nlines (int nlines);
602 * delete NLINES by scrolling up the region <Scroll_r1, Scroll_r2>
603 \*----------------------------------------------------------------------*/
604 void SLtt_delete_nlines (int nlines
)
606 SLtt_normal_video ();
610 # if defined (EMX_VIDEO)
611 v_attrib (Attribute_Byte
);
612 v_scroll (0, Scroll_r1
, SLtt_Screen_Cols
-1, Scroll_r2
, nlines
, V_SCROLL_UP
);
613 # else /* EMX_VIDEO */
614 # if defined (__os2__)
616 Line_Buffer
[0] = ' '; Line_Buffer
[1] = Attribute_Byte
;
617 VioScrollUp (Scroll_r1
, 0, Scroll_r2
, SLtt_Screen_Cols
-1,
618 nlines
, (PCH
) Line_Buffer
, 0);
621 # if defined (USE_ASM)
622 /* This has the effect of pulling all lines below it up */
624 asm mov ah
, 6 /* int 6h */
626 asm mov ch
, byte ptr Scroll_r1
627 asm mov dx
, SLtt_Screen_Cols
629 asm mov dh
, byte ptr Scroll_r2
630 asm mov bh
, byte ptr Attribute_Byte
635 # if defined (__WATCOMC__)
644 r
.h
.dl
= SLtt_Screen_Cols
- 1;
646 r
.h
.bh
= Attribute_Byte
;
647 int86 (0x10, &r
, &r
);
649 # endif /* USE_ASM */
650 # endif /* __os2__ */
651 # endif /* EMX_VIDEO */
657 /*----------------------------------------------------------------------*\
658 * Function: void SLtt_reverse_index (int nlines);
660 * scroll down the region <Scroll_r1, Scroll_r2> by NLINES
661 \*----------------------------------------------------------------------*/
662 void SLtt_reverse_index (int nlines
)
664 SLtt_normal_video ();
668 # if defined (EMX_VIDEO)
669 v_attrib (Attribute_Byte
);
670 v_scroll (0, Scroll_r1
, SLtt_Screen_Cols
-1, Scroll_r2
, nlines
,
672 # else /* EMX_VIDEO */
673 # if defined (__os2__)
675 Line_Buffer
[0] = ' '; Line_Buffer
[1] = Attribute_Byte
;
676 VioScrollDn (Scroll_r1
, 0, Scroll_r2
, SLtt_Screen_Cols
-1,
677 nlines
, (PCH
) Line_Buffer
, 0);
680 # if defined (USE_ASM)
682 asm mov ch
, byte ptr Scroll_r1
683 asm mov dx
, SLtt_Screen_Cols
685 asm mov dh
, byte ptr Scroll_r2
686 asm mov bh
, byte ptr Attribute_Byte
688 asm mov al
, byte ptr nlines
694 # if defined (__WATCOMC__)
701 r
.h
.dl
= SLtt_Screen_Cols
- 1;
703 r
.h
.bh
= Attribute_Byte
;
704 int86 (0x10, &r
, &r
);
706 # endif /* USE_ASM */
707 # endif /* __os2__ */
708 # endif /* EMX_VIDEO */
714 /*----------------------------------------------------------------------*\
715 * Function: static void slvid_invert_region (int top_row, int bot_row);
717 * invert the display in the region, top_row <= row < bot_row
718 \*----------------------------------------------------------------------*/
719 static void slvid_invert_region (int top_row
, int bot_row
)
724 # if defined (EMX_VIDEO)
727 for (row
= top_row
; row
< bot_row
; row
++)
729 v_getline (Line_Buffer
, 0, row
, SLtt_Screen_Cols
);
730 for (col
= 1; col
< SLtt_Screen_Cols
* 2; col
+= 2)
731 Line_Buffer
[col
] ^= 0xff;
732 v_putline (Line_Buffer
, 0, row
, SLtt_Screen_Cols
);
734 # else /* EMX_VIDEO */
737 USHORT length
= SLtt_Screen_Cols
* 2;
739 for (row
= top_row
; row
< bot_row
; row
++)
741 VioReadCellStr ((PCH
)Line_Buffer
, &length
, row
, 0, 0);
742 for (col
= 1; col
< length
; col
+= 2)
743 Line_Buffer
[col
] ^= 0xff;
744 VioWrtCellStr ((PCH
)Line_Buffer
, length
, row
, 0, 0);
747 # if defined (__GO32__) || defined (__WATCOMC__)
748 unsigned char buf
[2 * 180 * 80]; /* 180 cols x 80 rows */
749 unsigned char *b
, *bmax
;
751 b
= buf
+ 1 + 2 * SLtt_Screen_Cols
* top_row
;
752 bmax
= buf
+ 1 + 2 * SLtt_Screen_Cols
* bot_row
;
753 ScreenRetrieve (buf
);
760 # else /* __GO32__ or __WATCOMC__ */
761 register unsigned short ch
, sh
;
762 register unsigned short *pmin
= mkScreenPointer (top_row
, 0);
763 register unsigned short *pmax
= mkScreenPointer (bot_row
, 0);
770 *pmin
= (ch
& 0xFF00) | (sh
& 0x00FF);
773 # endif /* __GO32__ or __WATCOMC__ */
774 # endif /* __os2__ */
775 # endif /* EMX_VIDEO */
781 /*----------------------------------------------------------------------*\
782 * Function: void SLtt_beep (void);
784 * signal error by a "bell" condition, the type of signal is governed
785 * by the value of SLtt_Ignore_Beep:
790 * 4 special visual bell (only flash the bottom status line)
792 * these may be combined:
793 * eg, 3 = audible visual bell.
794 * but if both the visual bell and the "special" visual bell are specified,
795 * only the special bell is used.
796 \*----------------------------------------------------------------------*/
797 void SLtt_beep (void)
799 int audible
; /* audible bell */
800 int special
= 0; /* first row to invert */
801 int visual
= 0; /* final row to invert */
802 if (!SLtt_Ignore_Beep
) return;
804 audible
= (SLtt_Ignore_Beep
& 1);
805 if ( (SLtt_Ignore_Beep
& 4) )
807 special
= SLtt_Screen_Rows
- 1;
808 visual
= special
--; /* only invert bottom status line */
810 else if ( (SLtt_Ignore_Beep
& 2) )
812 visual
= SLtt_Screen_Rows
;
815 if (visual
) slvid_invert_region (special
, visual
);
816 #if defined (EMX_VIDEO)
817 if (audible
) /*sound (1500)*/; _sleep2 (100); if (audible
) /* nosound () */;
820 if (audible
) DosBeep (1500, 100); else DosSleep (100);
822 # elif defined(WIN32)
825 if (audible
) sound (1500); delay (100); if (audible
) nosound ();
828 if (visual
) slvid_invert_region (special
, visual
);
831 /*----------------------------------------------------------------------*\
832 * Function: void SLtt_del_eol (void);
834 * delete from the current cursor position to the end of the row
835 \*----------------------------------------------------------------------*/
836 void SLtt_del_eol (void)
841 # if defined (GO32_VIDEO) || defined (EMX_VIDEO)
842 if (Current_Color
!= JNO_COLOR
) SLtt_normal_video ();
843 slvid_deleol (Cursor_Col
);
844 # else /* GO32_VIDEO or EMX_VIDEO */
847 if (Current_Color
!= JNO_COLOR
) SLtt_normal_video ();
849 VioWrtNCell ((BYTE
*)&w
, (SLtt_Screen_Cols
- Cursor_Col
),
850 Cursor_Row
, Cursor_Col
, 0);
852 unsigned short *p
= mkScreenPointer (Cursor_Row
, Cursor_Col
);
853 int n
= SLtt_Screen_Cols
- Cursor_Col
;
855 # if defined (HAS_LINEAR_SCREEN)
856 unsigned short *pmax
= p
+ n
;
858 if (Current_Color
!= JNO_COLOR
) SLtt_normal_video ();
860 while (p
< pmax
) *p
++ = w
;
861 # else /* HAS_LINEAR_SCREEN */
862 if (Current_Color
!= JNO_COLOR
) SLtt_normal_video ();
873 # endif /* HAS_LINEAR_SCREEN */
874 # endif /* __os2__ */
875 # endif /* GO32_VIDEO or EMX_VIDEO */
881 /*----------------------------------------------------------------------*\
882 * Function: void SLtt_reverse_video (int color);
884 * set Attribute_Byte corresponding to COLOR.
885 * Use Current_Color to remember the color which was set.
886 * convert from the COLOR number to the attribute value.
887 \*----------------------------------------------------------------------*/
888 void SLtt_reverse_video (int color
)
890 Attribute_Byte
= Color_Map
[color
];
891 Current_Color
= color
;
894 /*----------------------------------------------------------------------*\
895 * Function: void SLtt_normal_video (void);
897 * reset the attributes for normal video
898 \*----------------------------------------------------------------------*/
899 void SLtt_normal_video (void)
901 SLtt_reverse_video (JNORMAL_COLOR
);
904 #if defined (USE_ASM)
905 /*----------------------------------------------------------------------*\
906 * Function: static unsigned short *video_write (register unsigned char *pp,
907 * register unsigned char *p,
908 * register unsigned short *pos)
910 * write out (P - PP) characters from the array pointed to by PP
911 * at position (POS, Cursor_Row) in the current Attribute_Byte
913 * increment POS to reflect the number of characters sent and
914 * return the it as a pointer
915 \*----------------------------------------------------------------------*/
916 static unsigned short *video_write (register unsigned char *pp
,
917 register unsigned char *p
,
918 register unsigned short *pos
)
920 int n
= (int) (p
- pp
); /* num of characters of PP to write */
926 /* set up register for BOTH fast and slow */
927 asm mov bx
, SLtt_Msdos_Cheap_Video
929 /* These are the registers needed for both fast AND slow */
930 asm mov ah
, byte ptr Attribute_Byte
932 asm lds si
, dword ptr pp
933 asm les di
, dword ptr pos
936 asm cmp bx
, 0 /* cheap video test */
939 asm mov dx
, CGA_STATUS
945 /* wait for retrace */
956 /* move a character out */
965 /* -------------- slow video, vertical retace and pump --------------*/
970 asm jnz L_slow_blank_loop
981 asm loop L_slow_blank2
984 /*-------------- Fast video --------------*/
998 /*----------------------------------------------------------------------*\
999 * Function: static void write_attributes (unsigned short *src,
1002 * Copy COUNT character/color pairs from the array pointed to by
1003 * SRC to the screen at position (0,Cursor_Row).
1004 * NB: SRC contains character/color pairs -- the color must be converted to
1005 * an ansi attribute.
1008 * 1) a combination of string/attributes
1009 * 2) each string of continuous colour
1011 * approach 2) is used for assembler output, while 1) is used when a higher
1012 * level API is available or direct to memory writing is possible: emx video
1013 * routines, os/2, go32, watcom.
1014 \*----------------------------------------------------------------------*/
1015 static void write_attributes (unsigned short *src
, int count
)
1017 register unsigned char *p
= Line_Buffer
;
1018 register unsigned short pair
;
1020 register unsigned char * org_src
= src
;
1024 #if !defined (USE_ASM)
1025 # if defined (HAS_LINEAR_SCREEN)
1026 register unsigned short *pos
= mkScreenPointer (Cursor_Row
, 0);
1030 /* write into a character/attribute pair */
1033 pair
= *(src
++); /* character/color pair */
1034 SLtt_reverse_video (pair
>> 8); /* color change */
1035 # if defined (HAS_LINEAR_SCREEN)
1036 *(pos
++) = ((unsigned short) Attribute_Byte
<< 8) | pair
& 0xff;
1038 # if defined(EMX_VIDEO) || !defined(WIN32)
1039 *(p
++) = pair
& 0xff; /* character byte */
1040 *(p
++) = Attribute_Byte
; /* attribute byte */
1042 /* WIN32 for now... */
1043 *(p
++) = pair
& 0xff;
1048 # if !defined (HAS_LINEAR_SCREEN)
1049 # if defined (EMX_VIDEO)
1050 v_putline (Line_Buffer
, Cursor_Col
, Cursor_Row
, count
);
1051 # else /* EMX_VIDEO */
1052 # if defined (__os2__)
1053 VioWrtCellStr ((PCH
)Line_Buffer
, (USHORT
)(2 * count
),
1054 (USHORT
)Cursor_Row
, (USHORT
)Cursor_Col
, 0);
1055 # elif defined(WIN32)
1056 /* do color attributes later */
1058 coord
.X
= Cursor_Col
;
1059 coord
.Y
= Cursor_Row
;
1060 WriteConsoleOutputCharacter(hStdout
, p
, count
, coord
, &bytes
);
1062 /* write color attributes */
1065 src
= org_src
; /* restart the src pointer */
1067 /* write into attributes only */
1070 pair
= *(src
++); /* character/color pair */
1071 SLtt_reverse_video (pair
>> 8); /* color change */
1072 *(p
++) = Attribute_Byte
; /* attribute byte */
1073 *(p
++) = 0; /* what's this for? */
1076 WriteConsoleOutputAttribute(hStdout
, Line_Buffer
, count
, coord
, &bytes
);
1077 # else /* __os2__ */
1078 /* ScreenUpdateLine (void *virtual_screen_line, int row); */
1083 ScreenPutChar ((int)p
[0], (int)p
[1], n
++, Cursor_Row
);
1086 # endif /* EMX_VIDEO */
1087 # endif /* __os2__ */
1088 # endif /* HAS_LINEAR_SCREEN */
1089 #else /* not USE_ASM */
1090 unsigned char ch
, color
;
1091 register unsigned short *pos
= mkScreenPointer (Cursor_Row
, 0);
1095 pair
= *(src
++); /* character/color pair */
1096 ch
= pair
& 0xff; /* character value */
1097 color
= pair
>> 8; /* color value */
1098 if (color
!= Current_Color
) /* need a new color */
1100 if (p
!= Line_Buffer
)
1102 pos
= video_write (Line_Buffer
, p
, pos
);
1105 SLtt_reverse_video (color
); /* change color */
1109 pos
= video_write (Line_Buffer
, p
, pos
);
1110 #endif /* not USE_ASM */
1113 /*----------------------------------------------------------------------*\
1114 * Function: void SLtt_smart_puts (unsigned short *new_string,
1115 * unsigned short *old_string,
1116 * int len, int row);
1118 * puts NEW_STRING, which has length LEN, at row ROW. NEW_STRING contains
1119 * characters/colors packed in the form value = ((color << 8) | (ch));
1121 * the puts tries to avoid overwriting the same characters/colors
1123 * OLD_STRING is not used, maintained for compatibility with other systems
1124 \*----------------------------------------------------------------------*/
1125 void SLtt_smart_puts (unsigned short *new_string
,
1126 unsigned short *old_string
,
1132 write_attributes (new_string
, len
);
1135 /*----------------------------------------------------------------------*\
1136 * Function: void SLtt_reset_video (void);
1137 \*----------------------------------------------------------------------*/
1138 void SLtt_reset_video (void)
1140 SLtt_goto_rc (SLtt_Screen_Rows
- 1, 0);
1141 #ifdef HAS_SAVE_SCREEN
1144 Attribute_Byte
= 0x07;
1145 Current_Color
= JNO_COLOR
;
1150 void wide_width (void)
1154 void narrow_width (void)
1159 /*----------------------------------------------------------------------*\
1160 * Function: void SLtt_cls (void);
1161 \*----------------------------------------------------------------------*/
1162 void SLtt_cls (void)
1169 SLtt_normal_video ();
1170 #if defined (__GO32__) || defined (__WATCOMC__) || defined (EMX_VIDEO)
1171 SLtt_reset_scroll_region ();
1172 SLtt_goto_rc (0, 0);
1173 SLtt_delete_nlines (SLtt_Screen_Rows
);
1174 #else /* __GO32__ or __WATCOMC__ or EMX_VIDEO */
1177 Line_Buffer
[0] = ' '; Line_Buffer
[1] = Attribute_Byte
;
1178 VioScrollUp (0, 0, -1, -1, -1, (PCH
)Line_Buffer
, 0);
1180 # elif defined(WIN32)
1181 /* clear the WIN32 screen in one shot */
1187 (void) FillConsoleOutputCharacter(hStdout
,
1189 csbiInfo
.dwSize
.Y
* csbiInfo
.dwSize
.X
,
1193 /* now set screen to the current attribute */
1194 ch
= Attribute_Byte
;
1195 (void) FillConsoleOutputAttribute(hStdout
,
1197 csbiInfo
.dwSize
.Y
* csbiInfo
.dwSize
.X
,
1200 # else /* __os2__ */
1201 asm mov dx
, SLtt_Screen_Cols
1203 asm mov ax
, SLtt_Screen_Rows
1209 asm mov bh
, byte ptr Attribute_Byte
1211 # endif /* __os2__ */
1212 #endif /* __GO32__ or __WATCOMC__ or EMX_VIDEO */
1215 /*----------------------------------------------------------------------*\
1216 * Function: void SLtt_putchar (char ch);
1218 * put CH on the screen in the current position.
1219 * this function is called assuming that cursor is in correct position
1220 \*----------------------------------------------------------------------*/
1222 void SLtt_putchar (char ch
)
1224 #if !defined (GO32_VIDEO) && !defined (EMX_VIDEO)
1225 unsigned short p
, *pp
;
1231 if (Current_Color
) SLtt_normal_video ();
1232 slvid_getxy (); /* get current position */
1235 case 7: /* ^G - break */
1236 SLtt_beep (); break;
1237 case 8: /* ^H - backspace */
1238 SLtt_goto_rc (Cursor_Row
, Cursor_Col
- 1); break;
1239 case 13: /* ^M - carriage return */
1240 SLtt_goto_rc (Cursor_Row
, 0); break;
1241 default: /* write character to screen */
1242 #if defined (EMX_VIDEO)
1244 #else /* EMX_VIDEO */
1246 VioWrtCharStrAtt (&ch
, 1, Cursor_Row
, Cursor_Col
,
1247 (BYTE
*)&Attribute_Byte
, 0);
1248 # elif defined(WIN32)
1249 WriteConsole(hStdout
, &ch
, 1, &bytes
, NULL
);
1250 # else /* __os2__ */
1252 ScreenPutChar ((int) ch
, Attribute_Byte
, Cursor_Col
, Cursor_Row
);
1253 # else /* GO32_VIDEO */
1254 pp
= mkScreenPointer (Cursor_Row
, Cursor_Col
);
1255 p
= (Attribute_Byte
<< 8) | (unsigned char) ch
;
1261 # endif /* GO32_VIDEO */
1262 # endif /* __os2__ */
1263 #endif /* EMX_VIDEO */
1264 SLtt_goto_rc (Cursor_Row
, Cursor_Col
+ 1);
1268 /*----------------------------------------------------------------------*\
1269 * Function: void SLtt_set_color (int obj, char *what, char *fg, char *bg);
1271 * set foreground and background colors of OBJ to the attributes which
1272 * correspond to the names FG and BG, respectively.
1274 * WHAT is the name corresponding to the object OBJ, but is not used in
1276 \*----------------------------------------------------------------------*/
1277 void SLtt_set_color (int obj
, char *what
, char *fg
, char *bg
)
1279 int i
, b
= -1, f
= -1;
1286 if ( !IsColor
|| (obj
< 0) || (obj
>= JMAX_COLORS
))
1289 for (i
= 0; i
< JMAX_COLOR_NAMES
; i
++ )
1291 if (!strcmp (fg
, Color_Names
[i
]))
1298 for (i
= 0; i
< JMAX_COLOR_NAMES
; i
++)
1300 if (!strcmp (bg
, Color_Names
[i
]))
1302 if (Blink_Killed
) b
= i
; else b
= i
& 0x7;
1306 if ((f
== -1) || (b
== -1) || (f
== b
)) return;
1308 Color_Map
[obj
] = (b
<< 4) | f
;
1313 "black", "blue", "green", "cyan",
1315 "red", "magenta", "brown", "lightgray",
1317 "gray", "brightblue", "brightgreen", "brightcyan",
1319 "brightred", "brightmagenta", "yellow", "white"
1322 /* these aren't all right yet */
1325 case 0: newcolor
= 0; break;
1326 case 1: newcolor
= FOREGROUND_BLUE
; break;
1327 case 2: newcolor
= FOREGROUND_GREEN
; break;
1328 case 3: newcolor
= FOREGROUND_GREEN
| FOREGROUND_BLUE
; break;
1330 case 4: newcolor
= FOREGROUND_RED
; break;
1331 case 5: newcolor
= FOREGROUND_RED
| FOREGROUND_BLUE
; break;
1332 case 6: newcolor
= FOREGROUND_GREEN
| FOREGROUND_RED
; break;
1333 case 7: newcolor
= FOREGROUND_RED
| FOREGROUND_GREEN
| FOREGROUND_BLUE
| FOREGROUND_INTENSITY
; break;
1335 case 8: newcolor
= FOREGROUND_BLUE
| FOREGROUND_RED
| FOREGROUND_GREEN
; break;
1336 case 9: newcolor
= FOREGROUND_BLUE
| FOREGROUND_INTENSITY
; break;
1337 case 10: newcolor
= FOREGROUND_GREEN
| FOREGROUND_INTENSITY
; break;
1338 case 11: newcolor
= FOREGROUND_GREEN
| FOREGROUND_BLUE
| FOREGROUND_INTENSITY
; break;
1340 case 12: newcolor
= FOREGROUND_RED
| FOREGROUND_INTENSITY
; break;
1341 case 13: newcolor
= FOREGROUND_RED
| FOREGROUND_BLUE
| FOREGROUND_INTENSITY
; break;
1342 case 14: newcolor
= FOREGROUND_GREEN
| FOREGROUND_BLUE
| FOREGROUND_INTENSITY
; break;
1343 case 15: newcolor
= FOREGROUND_RED
| FOREGROUND_GREEN
| FOREGROUND_BLUE
| FOREGROUND_INTENSITY
; break;
1349 "black", "blue", "green", "cyan",
1351 "red", "magenta", "brown", "lightgray",
1353 "gray", "brightblue", "brightgreen", "brightcyan",
1355 "brightred", "brightmagenta", "yellow", "white"
1360 case 0: newcolor
|= 0; break;
1361 case 1: newcolor
|= BACKGROUND_BLUE
; break;
1362 case 2: newcolor
|= BACKGROUND_GREEN
; break;
1363 case 3: newcolor
|= BACKGROUND_GREEN
| BACKGROUND_BLUE
; break;
1365 case 4: newcolor
|= BACKGROUND_RED
; break;
1366 case 5: newcolor
|= BACKGROUND_RED
| BACKGROUND_BLUE
; break;
1367 case 6: newcolor
|= BACKGROUND_GREEN
| BACKGROUND_RED
; break;
1368 case 7: newcolor
|= BACKGROUND_RED
| BACKGROUND_GREEN
| BACKGROUND_BLUE
| BACKGROUND_INTENSITY
; break;
1370 case 8: newcolor
|= BACKGROUND_RED
| BACKGROUND_GREEN
| BACKGROUND_BLUE
; break;
1371 case 9: newcolor
|= BACKGROUND_BLUE
| BACKGROUND_INTENSITY
; break;
1372 case 10: newcolor
|= BACKGROUND_GREEN
| BACKGROUND_INTENSITY
; break;
1373 case 11: newcolor
|= BACKGROUND_GREEN
| BACKGROUND_BLUE
| BACKGROUND_INTENSITY
; break;
1375 case 12: newcolor
|= BACKGROUND_RED
| BACKGROUND_INTENSITY
; break;
1376 case 13: newcolor
|= BACKGROUND_RED
| BACKGROUND_BLUE
| BACKGROUND_INTENSITY
; break;
1377 case 14: newcolor
|= BACKGROUND_GREEN
| BACKGROUND_BLUE
| BACKGROUND_INTENSITY
; break;
1378 case 15: newcolor
|= BACKGROUND_RED
| BACKGROUND_GREEN
| BACKGROUND_BLUE
| BACKGROUND_INTENSITY
; break;
1382 Color_Map
[obj
] = newcolor
;
1385 /* if we're setting the normal color, and the attribute byte hasn't
1386 been set yet, set it to the new color */
1387 if ((obj
== 0) && (Attribute_Byte
== 0))
1388 SLtt_reverse_video (0);
1391 /*----------------------------------------------------------------------*\
1392 * Function: void SLtt_get_terminfo (void)
1393 \*----------------------------------------------------------------------*/
1394 void SLtt_get_terminfo (void)
1397 SLtt_Screen_Rows
= csbiInfo
.dwSize
.Y
;
1398 SLtt_Screen_Cols
= csbiInfo
.dwSize
.X
;
1401 SLtt_Screen_Rows
= ScreenRows ();
1402 SLtt_Screen_Cols
= ScreenCols ();
1406 /*----------------------------------------------------------------------*\
1407 * Function: void SLtt_init_video (void);
1408 \*----------------------------------------------------------------------*/
1409 void SLtt_init_video (void)
1411 #if defined (EMX_VIDEO)
1415 #ifdef HAS_SAVE_SCREEN
1419 Cursor_Row
= Cursor_Col
= 0;
1421 #if defined (EMX_VIDEO)
1424 if ( v_hardware () != V_MONOCHROME
) IsColor
= 1; else IsColor
= 0;
1426 v_getxy(&OldCol
,&OldRow
);
1431 if (_osmode
== OS2_MODE
)
1434 /* Enable high-intensity background colors */
1435 VIOINTENSITY RequestBlock
;
1436 RequestBlock
.cb
= sizeof (RequestBlock
);
1437 RequestBlock
.type
= 2; RequestBlock
.fs
= 1;
1438 VioSetState (&RequestBlock
, 0); /* nop if !fullscreen */
1444 Blink_Killed
= 1; /* seems to work */
1448 if (!Attribute_Byte
)
1450 /* find the attribute currently under the cursor */
1451 v_getline (Line_Buffer
, OldCol
, OldRow
, 1);
1452 Attribute_Byte
= Line_Buffer
[1];
1453 set_color_from_attribute (Attribute_Byte
);
1456 v_attrib (Attribute_Byte
);
1457 /* SLtt_Term_Cannot_Insert = 1; */
1458 #else /* EMX_VIDEO */
1460 IsColor
= 1; /* is it really? */
1462 /* Enable high-intensity background colors */
1463 VIOINTENSITY RequestBlock
;
1464 RequestBlock
.cb
= sizeof (RequestBlock
);
1465 RequestBlock
.type
= 2; RequestBlock
.fs
= 1;
1466 VioSetState (&RequestBlock
, 0); /* nop if !fullscreen */
1470 if (!Attribute_Byte
)
1472 /* find the attribute currently under the cursor */
1473 USHORT Length
= 2, Row
, Col
;
1474 VioGetCurPos (&Row
, &Col
, 0);
1475 VioReadCellStr ((PCH
)Line_Buffer
, &Length
, Row
, Col
, 0);
1476 Attribute_Byte
= Line_Buffer
[1];
1477 set_color_from_attribute (Attribute_Byte
);
1479 # elif defined(WIN32)
1480 /* initialize the WIN32 console */
1481 IsColor
= 1; /* yes, the WIN32 console can do color (on a color monitor) */
1483 # if defined (__GO32__) || defined (__WATCOMC__)
1485 SLtt_Term_Cannot_Insert
= 1;
1487 Video_Base
= (unsigned char *) ScreenPrimary
;
1489 if (!Attribute_Byte
) Attribute_Byte
= 0x17;
1490 IsColor
= 1; /* is it really? */
1496 r
.x
.eax
= 0x1003; r
.x
.ebx
= 0;
1498 r
.x
.ax
= 0x1003; r
.x
.bx
= 0;
1500 int86 (0x10, &r
, &r
);
1503 # else /* (__GO32__ or __WATCOMC__ */
1505 unsigned char *p
= (unsigned char far
*) 0x00400049L
;
1508 Video_Status_Port
= MONO_STATUS
;
1509 Video_Base
= (unsigned char *) MK_FP (0xb000,0000);
1514 Video_Status_Port
= CGA_STATUS
;
1515 Video_Base
= (unsigned char *) MK_FP (0xb800,0000);
1520 /* test for video adapter type. Of primary interest is whether there is
1521 * snow or not. Assume snow if the card is color and not EGA or greater.
1524 /* Use Ralf Brown test for EGA or greater */
1534 asm mov SLtt_Msdos_Cheap_Video
, bx
1535 asm mov ax
, Attribute_Byte
1539 asm mov Attribute_Byte
, ax
1549 asm mov SLtt_Msdos_Cheap_Video
, ax
1551 asm mov ax
, Attribute_Byte
1555 asm mov Attribute_Byte
, ax
1557 /* toggle the blink bit so we can use hi intensity background */
1558 if (IsColor
&& !SLtt_Msdos_Cheap_Video
)
1565 # endif /* __GO32__ or __WATCOMC__ */
1566 # endif /* __os2__ */
1567 #endif /* EMX_VIDEO */
1568 SLtt_set_scroll_region (0, SLtt_Screen_Rows
);
1569 SLtt_Use_Ansi_Colors
= IsColor
;
1572 /*----------------------------------------------------------------------*\
1573 * Function: int SLtt_flush_output (void);
1574 \*----------------------------------------------------------------------*/
1575 int SLtt_flush_output (void)
1581 int SLtt_set_cursor_visibility (int show
)
1587 void SLtt_set_mono (int obj_unused
, char *unused
, SLtt_Char_Type c_unused
)
1594 /* /////////////////////// end of file (c source) ///////////////////// */