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
= (unsigned char*)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
, (char*)p
, count
, coord
, &bytes
);
1062 /* write color attributes */
1065 src
= (unsigned short*)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
, (WORD
*)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
.dwMaximumWindowSize
.Y
* csbiInfo
.dwMaximumWindowSize
.X
,
1193 /* now set screen to the current attribute */
1194 ch
= Attribute_Byte
;
1195 (void) FillConsoleOutputAttribute(hStdout
,
1197 csbiInfo
.dwMaximumWindowSize
.Y
* csbiInfo
.dwMaximumWindowSize
.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
;
1262 # endif /* GO32_VIDEO */
1263 # endif /* __os2__ */
1264 #endif /* EMX_VIDEO */
1265 SLtt_goto_rc (Cursor_Row
, Cursor_Col
+ 1);
1269 /*----------------------------------------------------------------------*\
1270 * Function: void SLtt_set_color (int obj, char *what, char *fg, char *bg);
1272 * set foreground and background colors of OBJ to the attributes which
1273 * correspond to the names FG and BG, respectively.
1275 * WHAT is the name corresponding to the object OBJ, but is not used in
1277 \*----------------------------------------------------------------------*/
1278 void SLtt_set_color (int obj
, char *what
, char *fg
, char *bg
)
1280 int i
, b
= -1, f
= -1;
1287 if ( !IsColor
|| (obj
< 0) || (obj
>= JMAX_COLORS
))
1290 for (i
= 0; i
< JMAX_COLOR_NAMES
; i
++ )
1292 if (!strcmp (fg
, Color_Names
[i
]))
1299 for (i
= 0; i
< JMAX_COLOR_NAMES
; i
++)
1301 if (!strcmp (bg
, Color_Names
[i
]))
1303 if (Blink_Killed
) b
= i
; else b
= i
& 0x7;
1307 if ((f
== -1) || (b
== -1) || (f
== b
)) return;
1309 Color_Map
[obj
] = (b
<< 4) | f
;
1314 "black", "blue", "green", "cyan",
1316 "red", "magenta", "brown", "lightgray",
1318 "gray", "brightblue", "brightgreen", "brightcyan",
1320 "brightred", "brightmagenta", "yellow", "white"
1323 /* these aren't all right yet */
1326 case 0: newcolor
= 0; break;
1327 case 1: newcolor
= FOREGROUND_BLUE
; break;
1328 case 2: newcolor
= FOREGROUND_GREEN
; break;
1329 case 3: newcolor
= FOREGROUND_GREEN
| FOREGROUND_BLUE
; break;
1331 case 4: newcolor
= FOREGROUND_RED
; break;
1332 case 5: newcolor
= FOREGROUND_RED
| FOREGROUND_BLUE
; break;
1333 case 6: newcolor
= FOREGROUND_GREEN
| FOREGROUND_RED
; break;
1334 case 7: newcolor
= FOREGROUND_RED
| FOREGROUND_GREEN
| FOREGROUND_BLUE
| FOREGROUND_INTENSITY
; break;
1336 case 8: newcolor
= FOREGROUND_BLUE
| FOREGROUND_RED
| FOREGROUND_GREEN
; break;
1337 case 9: newcolor
= FOREGROUND_BLUE
| FOREGROUND_INTENSITY
; break;
1338 case 10: newcolor
= FOREGROUND_GREEN
| FOREGROUND_INTENSITY
; break;
1339 case 11: newcolor
= FOREGROUND_GREEN
| FOREGROUND_BLUE
| FOREGROUND_INTENSITY
; break;
1341 case 12: newcolor
= FOREGROUND_RED
| FOREGROUND_INTENSITY
; break;
1342 case 13: newcolor
= FOREGROUND_RED
| FOREGROUND_BLUE
| FOREGROUND_INTENSITY
; break;
1343 case 14: newcolor
= FOREGROUND_GREEN
| FOREGROUND_BLUE
| FOREGROUND_INTENSITY
; break;
1344 case 15: newcolor
= FOREGROUND_RED
| FOREGROUND_GREEN
| FOREGROUND_BLUE
| FOREGROUND_INTENSITY
; break;
1350 "black", "blue", "green", "cyan",
1352 "red", "magenta", "brown", "lightgray",
1354 "gray", "brightblue", "brightgreen", "brightcyan",
1356 "brightred", "brightmagenta", "yellow", "white"
1361 case 0: newcolor
|= 0; break;
1362 case 1: newcolor
|= BACKGROUND_BLUE
; break;
1363 case 2: newcolor
|= BACKGROUND_GREEN
; break;
1364 case 3: newcolor
|= BACKGROUND_GREEN
| BACKGROUND_BLUE
; break;
1366 case 4: newcolor
|= BACKGROUND_RED
; break;
1367 case 5: newcolor
|= BACKGROUND_RED
| BACKGROUND_BLUE
; break;
1368 case 6: newcolor
|= BACKGROUND_GREEN
| BACKGROUND_RED
; break;
1369 case 7: newcolor
|= BACKGROUND_RED
| BACKGROUND_GREEN
| BACKGROUND_BLUE
| BACKGROUND_INTENSITY
; break;
1371 case 8: newcolor
|= BACKGROUND_RED
| BACKGROUND_GREEN
| BACKGROUND_BLUE
; break;
1372 case 9: newcolor
|= BACKGROUND_BLUE
| BACKGROUND_INTENSITY
; break;
1373 case 10: newcolor
|= BACKGROUND_GREEN
| BACKGROUND_INTENSITY
; break;
1374 case 11: newcolor
|= BACKGROUND_GREEN
| BACKGROUND_BLUE
| BACKGROUND_INTENSITY
; break;
1376 case 12: newcolor
|= BACKGROUND_RED
| BACKGROUND_INTENSITY
; break;
1377 case 13: newcolor
|= BACKGROUND_RED
| BACKGROUND_BLUE
| BACKGROUND_INTENSITY
; break;
1378 case 14: newcolor
|= BACKGROUND_GREEN
| BACKGROUND_BLUE
| BACKGROUND_INTENSITY
; break;
1379 case 15: newcolor
|= BACKGROUND_RED
| BACKGROUND_GREEN
| BACKGROUND_BLUE
| BACKGROUND_INTENSITY
; break;
1383 Color_Map
[obj
] = newcolor
;
1386 /* if we're setting the normal color, and the attribute byte hasn't
1387 been set yet, set it to the new color */
1388 if ((obj
== 0) && (Attribute_Byte
== 0))
1389 SLtt_reverse_video (0);
1392 /*----------------------------------------------------------------------*\
1393 * Function: void SLtt_get_terminfo (void)
1394 \*----------------------------------------------------------------------*/
1395 void SLtt_get_terminfo (void)
1398 SLtt_Screen_Rows
= csbiInfo
.dwMaximumWindowSize
.Y
;
1399 SLtt_Screen_Cols
= csbiInfo
.dwMaximumWindowSize
.X
;
1402 SLtt_Screen_Rows
= ScreenRows ();
1403 SLtt_Screen_Cols
= ScreenCols ();
1407 /*----------------------------------------------------------------------*\
1408 * Function: void SLtt_init_video (void);
1409 \*----------------------------------------------------------------------*/
1410 void SLtt_init_video (void)
1412 #if defined (EMX_VIDEO)
1416 #ifdef HAS_SAVE_SCREEN
1420 Cursor_Row
= Cursor_Col
= 0;
1422 #if defined (EMX_VIDEO)
1425 if ( v_hardware () != V_MONOCHROME
) IsColor
= 1; else IsColor
= 0;
1427 v_getxy(&OldCol
,&OldRow
);
1432 if (_osmode
== OS2_MODE
)
1435 /* Enable high-intensity background colors */
1436 VIOINTENSITY RequestBlock
;
1437 RequestBlock
.cb
= sizeof (RequestBlock
);
1438 RequestBlock
.type
= 2; RequestBlock
.fs
= 1;
1439 VioSetState (&RequestBlock
, 0); /* nop if !fullscreen */
1445 Blink_Killed
= 1; /* seems to work */
1449 if (!Attribute_Byte
)
1451 /* find the attribute currently under the cursor */
1452 v_getline (Line_Buffer
, OldCol
, OldRow
, 1);
1453 Attribute_Byte
= Line_Buffer
[1];
1454 set_color_from_attribute (Attribute_Byte
);
1457 v_attrib (Attribute_Byte
);
1458 /* SLtt_Term_Cannot_Insert = 1; */
1459 #else /* EMX_VIDEO */
1461 IsColor
= 1; /* is it really? */
1463 /* Enable high-intensity background colors */
1464 VIOINTENSITY RequestBlock
;
1465 RequestBlock
.cb
= sizeof (RequestBlock
);
1466 RequestBlock
.type
= 2; RequestBlock
.fs
= 1;
1467 VioSetState (&RequestBlock
, 0); /* nop if !fullscreen */
1471 if (!Attribute_Byte
)
1473 /* find the attribute currently under the cursor */
1474 USHORT Length
= 2, Row
, Col
;
1475 VioGetCurPos (&Row
, &Col
, 0);
1476 VioReadCellStr ((PCH
)Line_Buffer
, &Length
, Row
, Col
, 0);
1477 Attribute_Byte
= Line_Buffer
[1];
1478 set_color_from_attribute (Attribute_Byte
);
1480 # elif defined(WIN32)
1481 /* initialize the WIN32 console */
1482 IsColor
= 1; /* yes, the WIN32 console can do color (on a color monitor) */
1484 # if defined (__GO32__) || defined (__WATCOMC__)
1486 SLtt_Term_Cannot_Insert
= 1;
1488 Video_Base
= (unsigned char *) ScreenPrimary
;
1490 if (!Attribute_Byte
) Attribute_Byte
= 0x17;
1491 IsColor
= 1; /* is it really? */
1497 r
.x
.eax
= 0x1003; r
.x
.ebx
= 0;
1499 r
.x
.ax
= 0x1003; r
.x
.bx
= 0;
1501 int86 (0x10, &r
, &r
);
1504 # else /* (__GO32__ or __WATCOMC__ */
1506 unsigned char *p
= (unsigned char far
*) 0x00400049L
;
1509 Video_Status_Port
= MONO_STATUS
;
1510 Video_Base
= (unsigned char *) MK_FP (0xb000,0000);
1515 Video_Status_Port
= CGA_STATUS
;
1516 Video_Base
= (unsigned char *) MK_FP (0xb800,0000);
1521 /* test for video adapter type. Of primary interest is whether there is
1522 * snow or not. Assume snow if the card is color and not EGA or greater.
1525 /* Use Ralf Brown test for EGA or greater */
1535 asm mov SLtt_Msdos_Cheap_Video
, bx
1536 asm mov ax
, Attribute_Byte
1540 asm mov Attribute_Byte
, ax
1550 asm mov SLtt_Msdos_Cheap_Video
, ax
1552 asm mov ax
, Attribute_Byte
1556 asm mov Attribute_Byte
, ax
1558 /* toggle the blink bit so we can use hi intensity background */
1559 if (IsColor
&& !SLtt_Msdos_Cheap_Video
)
1566 # endif /* __GO32__ or __WATCOMC__ */
1567 # endif /* __os2__ */
1568 #endif /* EMX_VIDEO */
1569 SLtt_set_scroll_region (0, SLtt_Screen_Rows
);
1570 SLtt_Use_Ansi_Colors
= IsColor
;
1573 /*----------------------------------------------------------------------*\
1574 * Function: int SLtt_flush_output (void);
1575 \*----------------------------------------------------------------------*/
1576 int SLtt_flush_output (void)
1582 int SLtt_set_cursor_visibility (int show
)
1588 void SLtt_set_mono (int obj_unused
, char *unused
, SLtt_Char_Type c_unused
)
1595 /* /////////////////////// end of file (c source) ///////////////////// */