📄 slvideo.c
字号:
asm lds si, p
asm add si, 2
asm cld
asm rep movsw
asm mov ds, ax
asm mov si, bx
asm mov di, dx
# endif /* HAS_LINEAR_SCREEN */
# endif /* __os2__ */
# endif /* EMX_VIDEO */
# endif /* WIN32 */
#endif /* not GO32_VIDEO */
}
/*----------------------------------------------------------------------*\
* Function: void SLtt_erase_line (void);
*
* This function is *only* called on exit.
* It sets attribute byte to Black & White
\*----------------------------------------------------------------------*/
void SLtt_erase_line (void)
{
#ifndef WIN32
# if defined (GO32_VIDEO) || defined (EMX_VIDEO)
Attribute_Byte = 0x07;
slvid_deleol (0);
# else /* GO32_VIDEO or EMX_VIDEO */
# if defined (__os2__)
USHORT w;
Attribute_Byte = 0x07;
w = mkSpaceChar ();
VioWrtNCell ((BYTE*)&w, SLtt_Screen_Cols, Cursor_Row, 0, 0);
# else /* __os2__ */
unsigned short w;
unsigned short *p = mkScreenPointer (Cursor_Row, 0);
# if defined (HAS_LINEAR_SCREEN)
register unsigned short *pmax = p + SLtt_Screen_Cols;
Attribute_Byte = 0x07;
w = mkSpaceChar ();
while (p < pmax) *p++ = w;
# else /* HAS_LINEAR_SCREEN */
Attribute_Byte = 0x07;
w = mkSpaceChar ();
SNOW_CHECK;
asm mov dx, di
asm mov ax, w
asm mov cx, SLtt_Screen_Cols
asm les di, p
asm cld
asm rep stosw
asm mov di, dx
# endif /* HAS_LINEAR_SCREEN */
# endif /* __os2__ */
# endif /* GO32_VIDEO or EMX_VIDEO */
Current_Color = JNO_COLOR; /* since we messed with attribute byte */
#endif /* WIN32 */
}
/*----------------------------------------------------------------------*\
* Function: void SLtt_delete_nlines (int nlines);
*
* delete NLINES by scrolling up the region <Scroll_r1, Scroll_r2>
\*----------------------------------------------------------------------*/
void SLtt_delete_nlines (int nlines)
{
SLtt_normal_video ();
#ifndef WIN32
# if defined (EMX_VIDEO)
v_attrib (Attribute_Byte);
v_scroll (0, Scroll_r1, SLtt_Screen_Cols-1, Scroll_r2, nlines, V_SCROLL_UP);
# else /* EMX_VIDEO */
# if defined (__os2__)
{
Line_Buffer[0] = ' '; Line_Buffer[1] = Attribute_Byte;
VioScrollUp (Scroll_r1, 0, Scroll_r2, SLtt_Screen_Cols-1,
nlines, (PCH) Line_Buffer, 0);
}
# else /* __os2__ */
# if defined (USE_ASM)
/* This has the effect of pulling all lines below it up */
asm mov ax, nlines
asm mov ah, 6 /* int 6h */
asm xor cx, cx
asm mov ch, byte ptr Scroll_r1
asm mov dx, SLtt_Screen_Cols
asm dec dx
asm mov dh, byte ptr Scroll_r2
asm mov bh, byte ptr Attribute_Byte
asm int 10h
# else /* USE_ASM */
{
union REGS r;
# if defined (__WATCOMC__)
r.x.eax = nlines;
r.x.ecx = 0;
# else
r.x.ax = nlines;
r.x.cx = 0;
# endif
r.h.ah = 6;
r.h.ch = Scroll_r1;
r.h.dl = SLtt_Screen_Cols - 1;
r.h.dh = Scroll_r2;
r.h.bh = Attribute_Byte;
int86 (0x10, &r, &r);
}
# endif /* USE_ASM */
# endif /* __os2__ */
# endif /* EMX_VIDEO */
#endif /* WIN32 */
}
/*----------------------------------------------------------------------*\
* Function: void SLtt_reverse_index (int nlines);
*
* scroll down the region <Scroll_r1, Scroll_r2> by NLINES
\*----------------------------------------------------------------------*/
void SLtt_reverse_index (int nlines)
{
SLtt_normal_video ();
#ifndef WIN32
# if defined (EMX_VIDEO)
v_attrib (Attribute_Byte);
v_scroll (0, Scroll_r1, SLtt_Screen_Cols-1, Scroll_r2, nlines,
V_SCROLL_DOWN);
# else /* EMX_VIDEO */
# if defined (__os2__)
{
Line_Buffer[0] = ' '; Line_Buffer[1] = Attribute_Byte;
VioScrollDn (Scroll_r1, 0, Scroll_r2, SLtt_Screen_Cols-1,
nlines, (PCH) Line_Buffer, 0);
}
# else /* __os2__ */
# if defined (USE_ASM)
asm xor cx, cx
asm mov ch, byte ptr Scroll_r1
asm mov dx, SLtt_Screen_Cols
asm dec dx
asm mov dh, byte ptr Scroll_r2
asm mov bh, byte ptr Attribute_Byte
asm mov ah, 7
asm mov al, byte ptr nlines
asm int 10h
# else /* USE_ASM */
{
union REGS r;
r.h.al = nlines;
# if defined (__WATCOMC__)
r.x.ecx = 0;
# else
r.x.cx = 0;
# endif
r.h.ah = 7;
r.h.ch = Scroll_r1;
r.h.dl = SLtt_Screen_Cols - 1;
r.h.dh = Scroll_r2;
r.h.bh = Attribute_Byte;
int86 (0x10, &r, &r);
}
# endif /* USE_ASM */
# endif /* __os2__ */
# endif /* EMX_VIDEO */
#endif /* WIN32 */
}
/*----------------------------------------------------------------------*\
* Function: static void slvid_invert_region (int top_row, int bot_row);
*
* invert the display in the region, top_row <= row < bot_row
\*----------------------------------------------------------------------*/
static void slvid_invert_region (int top_row, int bot_row)
{
#ifndef WIN32
# if defined (EMX_VIDEO)
int row, col;
for (row = top_row; row < bot_row; row++)
{
v_getline (Line_Buffer, 0, row, SLtt_Screen_Cols);
for (col = 1; col < SLtt_Screen_Cols * 2; col += 2)
Line_Buffer [col] ^= 0xff;
v_putline (Line_Buffer, 0, row, SLtt_Screen_Cols);
}
# else /* EMX_VIDEO */
# ifdef __os2__
int row, col;
USHORT length = SLtt_Screen_Cols * 2;
for (row = top_row; row < bot_row; row++)
{
VioReadCellStr ((PCH)Line_Buffer, &length, row, 0, 0);
for (col = 1; col < length; col += 2)
Line_Buffer [col] ^= 0xff;
VioWrtCellStr ((PCH)Line_Buffer, length, row, 0, 0);
}
# else /* __os2__ */
# if defined (__GO32__) || defined (__WATCOMC__)
unsigned char buf [2 * 180 * 80]; /* 180 cols x 80 rows */
unsigned char *b, *bmax;
b = buf + 1 + 2 * SLtt_Screen_Cols * top_row;
bmax = buf + 1 + 2 * SLtt_Screen_Cols * bot_row;
ScreenRetrieve (buf);
while (b < bmax)
{
*b ^= 0xFF;
b += 2;
}
ScreenUpdate (buf);
# else /* __GO32__ or __WATCOMC__ */
register unsigned short ch, sh;
register unsigned short *pmin = mkScreenPointer (top_row, 0);
register unsigned short *pmax = mkScreenPointer (bot_row, 0);
while (pmin < pmax)
{
sh = *pmin;
ch = sh;
ch = ch ^ 0xFF00;
*pmin = (ch & 0xFF00) | (sh & 0x00FF);
pmin++;
}
# endif /* __GO32__ or __WATCOMC__ */
# endif /* __os2__ */
# endif /* EMX_VIDEO */
#endif /* WIN32 */
}
/*----------------------------------------------------------------------*\
* Function: void SLtt_beep (void);
*
* signal error by a "bell" condition, the type of signal is governed
* by the value of SLtt_Ignore_Beep:
*
* 0 silent bell
* 1 audible bell
* 2 visual bell
* 4 special visual bell (only flash the bottom status line)
*
* these may be combined:
* eg, 3 = audible visual bell.
* but if both the visual bell and the "special" visual bell are specified,
* only the special bell is used.
\*----------------------------------------------------------------------*/
void SLtt_beep (void)
{
int audible; /* audible bell */
int special = 0; /* first row to invert */
int visual = 0; /* final row to invert */
if (!SLtt_Ignore_Beep) return;
audible = (SLtt_Ignore_Beep & 1);
if ( (SLtt_Ignore_Beep & 4) )
{
special = SLtt_Screen_Rows - 1;
visual = special--; /* only invert bottom status line */
}
else if ( (SLtt_Ignore_Beep & 2) )
{
visual = SLtt_Screen_Rows;
}
if (visual) slvid_invert_region (special, visual);
#if defined (EMX_VIDEO)
if (audible) /*sound (1500)*/; _sleep2 (100); if (audible) /* nosound () */;
#else
# ifdef __os2__
if (audible) DosBeep (1500, 100); else DosSleep (100);
# elif defined(WIN32)
# else
if (audible) sound (1500); delay (100); if (audible) nosound ();
# endif
#endif
if (visual) slvid_invert_region (special, visual);
}
/*----------------------------------------------------------------------*\
* Function: void SLtt_del_eol (void);
*
* delete from the current cursor position to the end of the row
\*----------------------------------------------------------------------*/
void SLtt_del_eol (void)
{
#ifndef WIN32
# if defined (GO32_VIDEO) || defined (EMX_VIDEO)
if (Current_Color != JNO_COLOR) SLtt_normal_video ();
slvid_deleol (Cursor_Col);
# else /* GO32_VIDEO or EMX_VIDEO */
# ifdef __os2__
USHORT w;
if (Current_Color != JNO_COLOR) SLtt_normal_video ();
w = mkSpaceChar ();
VioWrtNCell ((BYTE*)&w, (SLtt_Screen_Cols - Cursor_Col),
Cursor_Row, Cursor_Col, 0);
# else /* __os2__ */
unsigned short *p = mkScreenPointer (Cursor_Row, Cursor_Col);
int n = SLtt_Screen_Cols - Cursor_Col;
unsigned short w;
# if defined (HAS_LINEAR_SCREEN)
unsigned short *pmax = p + n;
if (Current_Color != JNO_COLOR) SLtt_normal_video ();
w = mkSpaceChar ();
while (p < pmax) *p++ = w;
# else /* HAS_LINEAR_SCREEN */
if (Current_Color != JNO_COLOR) SLtt_normal_video ();
w = mkSpaceChar ();
SNOW_CHECK;
asm mov dx, di
asm les di, p
asm mov ax, w
asm mov cx, n
asm cld
asm rep stosw
asm mov di, dx
# endif /* HAS_LINEAR_SCREEN */
# endif /* __os2__ */
# endif /* GO32_VIDEO or EMX_VIDEO */
#endif /* WIN32 */
}
/*----------------------------------------------------------------------*\
* Function: void SLtt_reverse_video (int color);
*
* set Attribute_Byte corresponding to COLOR.
* Use Current_Color to remember the color which was set.
* convert from the COLOR number to the attribute value.
\*----------------------------------------------------------------------*/
void SLtt_reverse_video (int color)
{
Attribute_Byte = Color_Map [color];
Current_Color = color;
}
/*----------------------------------------------------------------------*\
* Function: void SLtt_normal_video (void);
*
* reset the attributes for normal video
\*----------------------------------------------------------------------*/
void SLtt_normal_video (void)
{
SLtt_reverse_video (JNORMAL_COLOR);
}
#if defined (USE_ASM)
/*----------------------------------------------------------------------*\
* Function: static unsigned short *video_write (register unsigned char *pp,
* register unsigned char *p,
* register unsigned short *pos)
*
* write out (P - PP) characters from the array pointed to by PP
* at position (POS, Cursor_Row) in the current Attribute_Byte
*
* increment POS to reflect the number of characters sent and
* return the it as a pointer
\*----------------------------------------------------------------------*/
static unsigned short *video_write (register unsigned char *pp,
register unsigned char *p,
register unsigned short *pos)
{
int n = (int) (p - pp); /* num of characters of PP to write */
asm push si
asm push ds
asm push di
/* set up register for BOTH fast and slow */
asm mov bx, SLtt_Msdos_Cheap_Video
/* These are the registers needed for both fast AND slow */
asm mov ah, byte ptr Attribute_Byte
asm mov cx, n
asm lds si, dword ptr pp
asm les di, dword ptr pos
asm cld
asm cmp bx, 0 /* cheap video test */
asm je L_fast
asm mov bx, ax
asm mov dx, CGA_STATUS
asm jg L_slow_blank
/* slow video */
asm cli
/* wait for retrace */
L_slow:
asm in al, dx
asm test al, 1
asm jnz L_slow
L_slow1:
asm in al, dx
asm test al, 1
asm jz L_slow1
/* move a character out */
asm mov ah, bh
asm lodsb
asm stosw
asm loop L_slow
asm sti
asm jmp done
/* -------------- slow video, vertical retace and pump --------------*/
L_slow_blank:
L_slow_blank_loop:
asm in al, dx
asm test al, 8
asm jnz L_slow_blank_loop
L_slow_blank1:
asm in al, dx
asm test al, 8
asm jz L_slow_blank1
/* write line */
asm mov ah, bh
L_slow_blank2:
asm lodsb
asm stosw
asm loop L_slow_blank2
asm jmp done
/*-------------- Fast video --------------*/
L_fast:
asm lodsb
asm stosw
asm loop L_fast
done:
asm pop di
asm pop ds
asm pop si
return (pos + n);
}
#endif /* USE_ASM */
/*----------------------------------------------------------------------*\
* Function: static void write_attributes (unsigned short *src,
* int count);
*
* Copy COUNT character/color pairs from the array pointed to by
* SRC to the screen at position (0,Cursor_Row).
* NB: SRC contains character/color pairs -- the color must be converted to
* an ansi attribute.
*
* Write out
* 1) a combination of string/attributes
* 2) each string of continuous colour
*
* approach 2) is used for assembler output, while 1) is used when a higher
* level API is available or direct to memory writing is possible: emx video
* routines, os/2, go32, watcom.
\*----------------------------------------------------------------------*/
static void write_attributes (unsigned short *src, int count)
{
register unsigned char *p = Line_Buffer;
register unsigned short pair;
#ifdef WIN32
register unsigned char * org_src = (unsigned char*)src;
COORD coord;
DWORD bytes;
#endif
#if !defined (USE_ASM)
# if defined (HAS_LINEAR_SCREEN)
register unsigned short *pos = mkScreenPointer (Cursor_Row, 0);
# endif
int n = count;
/* write into a character/attribute pair */
while (n-- > 0)
{
pair = *(src++); /* character/color pair */
SLtt_reverse_video (pair >> 8); /* color change */
# if defined (HAS_LINEAR_SCREEN)
*(pos++) = ((unsigned short) Attribute_Byte << 8) | pair & 0xff;
# else
# if defined(EMX_VIDEO) || !defined(WIN32)
*(p++) = pair & 0xff; /* character byte */
*(p++) = Attribute_Byte; /* attribute byte */
# else
/* WIN32 for now... */
*(p++) = pair & 0xff;
# endif
# endif
}
# if !defined (HAS_LINEAR_SCREEN)
# if defined (EMX_VIDEO)
v_putline (Line_Buffer, Cursor_Col, Cursor_Row, count);
# else /* EMX_VIDEO */
# if defined (__os2__)
VioWrtCellStr ((PCH)Line_Buffer, (USHORT)(2 * count),
(USHORT)Cursor_Row, (USHORT)Cursor_Col, 0);
# elif defined(WIN32)
/* do color attributes later */
p = Line_Buffer;
coord.X = Cursor_Col;
coord.Y = Cursor_Row;
WriteConsoleOutputCharacter(hStdout, (char*)p, count, coord, &bytes);
/* write color attributes */
p = Line_Buffer;
n = count;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -