📄 tscreen.cc
字号:
/* Copyright (C) 1996,1997 Robert H攈ne, see COPYING.RH for details */
/* This file is part of RHIDE. */
#ifdef __linux__
#define Uses_TScreen
#define Uses_TEvent
#define Uses_TDrawBuffer
#include <tv.h>
#include <ctype.h>
#include <fcntl.h>
#include <iostream.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <asm/io.h>
#include <sys/mman.h>
int dual_display = 0;
#ifdef __FreeBSD__
#include <ncurses.h>
#else
#include <curses.h>
#endif
#include <term.h>
#include <sys/ioctl.h>
#ifdef DEBUG
#ifdef __linux__
extern char *program_invocation_short_name;
#define LOG(s) cerr << program_invocation_short_name << ": " << s << "\n"
#else
#define LOG(s) cerr << __FILE__": " << s << "\n"
#endif
#else
#define LOG(s)
#endif
static int use_pc_chars = 1;
int timeout_wakeup,timer_value;
int vcs_fd=-1; /* virtual console system descriptor */
int tty_fd=-1; /* tty descriptor */
/* can I access the MDA ports ? */
int port_access;
FILE *tty_file;
unsigned short *mono_mem = NULL; /* mmapped mono video mem */
int mono_mem_desc=-1;
#ifndef __SAVECURSOR_OK
extern int cur_x,cur_y;
#endif
enum { PAL_MONO, PAL_LOW, PAL_HIGH };
static int palette;
static int force_redraw = 0;
#define DELAY_SIGALRM 100
/* lookup table to translate characters from pc set to standard ascii */
static unsigned char pctoascii[] =
{
" OOooooooooo!!!*><|!!O_|^V><--^V !\"#$%&'()*+,-./0123456789:;<=>?"
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~d"
"cueaaaaceeeiiiaaeafooouuyOUcLYPfaiounN--?--//!<>:%%|{+++++I+'++."
"`++}-+++`.+++=+++++++++++'.|-||-abipeouyooooooEn=+><()-=o..Vn2X "
};
inline int range(int test, int min, int max)
{
return test < min ? min : test > max ? max : test;
}
inline void safeput(char *&p, char *cap)
{
if (cap != NULL) while (*cap != '\0') *p++ = *cap++;
}
static struct termios old_term,new_term;
void startcurses()
{
char *terminal = getenv("TERM");
/* Save the terminal attributes so we can restore them later. */
/* for the user screen */
tcgetattr (STDOUT_FILENO, &old_term);
char *tty = ttyname(fileno(stdout));
char *ttyi = ttyname(fileno(stdin));
if (ttyi || tty)
{
if (tty)
tty_file = fopen(tty,"w+b");
else
tty_file = fopen(ttyi,"w+b");
}
else
{
fprintf(stderr,"Not connected to a terminal\n");
exit(-1);
}
if (!tty_file)
{
fprintf(stderr,"Could not open terminal '%s'\n", tty ? tty : ttyi);
exit(-1);
}
tty_fd = fileno(tty_file);
newterm(terminal,stdin,tty_file);
stdscr->_flags |= _ISPAD;
#if 1
keypad(stdscr, TRUE);
#endif
#if 0
cbreak();
noecho();
#endif
timeout(0); /* set getch() in non-blocking mode */
#if 1
if (vcs_fd < 0)
{
char buf[256], *p = buf;
safeput(p,enter_pc_charset_mode);
write(tty_fd, buf, p - buf);
}
#endif
if (vcs_fd >= 0)
{
palette = PAL_HIGH;
TScreen::screenMode = TScreen::smCO80;
use_pc_chars = 1;
}
else
{
if (!terminal)
{
palette = PAL_MONO;
TScreen::screenMode = TScreen::smMono;
use_pc_chars = 0;
}
else if (!strcmp(terminal,"console") ||
!strcmp(terminal,"linux"))
{
palette = PAL_HIGH;
TScreen::screenMode = TScreen::smCO80;
use_pc_chars = 1;
}
else if (has_colors())
{
palette = PAL_HIGH;
TScreen::screenMode = TScreen::smCO80;
use_pc_chars = 0;
}
else
{
palette = PAL_MONO;
TScreen::screenMode = TScreen::smMono;
use_pc_chars = 0;
}
}
/* Save the terminal attributes so we can restore them later. */
/* for our screen */
tcgetattr (tty_fd, &new_term);
}
void stopcurses()
{
endwin();
fclose(tty_file);
}
/*
* Converts colors from the large TV palette (16 foreground colors and
* 16 background colors) to ncurses small palette (8 foreground colors
* and 8 background colors).
*/
static int old_col = -1;
static int old_fore=-1,old_back=-1;
static void mapColor(char *&p, int col)
{
static char map[] = {0, 4, 2, 6, 1, 5, 3, 7};
int back,fore;
if (col == old_col)
return;
old_col = col;
back = (col >> 4) & 7;
fore = col & 15;
if (palette == PAL_LOW)
{
fore &= 7;
if (fore == back) fore = (fore + 1) & 7; /* kludge */
// if (fore != old_fore)
safeput(p, tparm(set_foreground,map[fore]));
// if (back != old_back)
safeput(p, tparm(set_background,map[back]));
}
else
{
if (fore != old_fore && back != old_back)
sprintf(p,"\033[%d;%d;%dm",fore>7?1:21,30+map[fore%8],40+map[back]);
else
{
if (fore != old_fore)
sprintf(p,"\033[%d;%dm",fore>7?1:21,30+map[fore%8]);
else
sprintf(p,"\033[%dm",40+map[back]);
}
p += strlen(p);
}
old_fore = fore;
old_back = back;
}
/*
* Writes a block of text.
*/
static void writeBlock(int dst, int len, ushort *old, ushort *src)
{
char out[4096], *p = out;
int col = -1;
#if 0
#define ___C() write(2,out,p-out)
#else
#define ___C()
#endif
#define __C()\
do { write(tty_fd, out, p - out); ___C(); } while(0)
#define _C() \
if (p > out+4000) \
{ \
__C();\
p = out; \
}
#ifdef __SAVECURSOR_OK
safeput(p, save_cursor );
#endif
safeput(p, tparm(cursor_address, dst / TScreen::screenWidth,
dst % TScreen::screenWidth));
while (len-- > 0)
{
int code = *src & 0xff;
int newcol = *src >> 8;
*old++ = *src++;
if (col == -1 || col != newcol) /* change color ? */
{
col = newcol;
if (palette == PAL_HIGH || palette == PAL_LOW)
mapColor(p, col);
else if (palette == PAL_MONO)
{
safeput(p, exit_attribute_mode);
if (col == 0x0f) safeput(p, enter_bold_mode);
else if (col == 0x70)
safeput(p, enter_reverse_mode);
}
}
if (!use_pc_chars || code < ' ') code = pctoascii[code];
*p++ = code;
_C();
}
#ifdef __SAVECURSOR_OK
safeput(p, restore_cursor);
#else
safeput(p, tparm(cursor_address, cur_y, cur_x));
#endif
if (palette == PAL_MONO) safeput(p, exit_attribute_mode);
__C();
}
ushort TScreen::startupMode = 0xFFFF;
ushort TScreen::startupCursor = 0;
ushort TScreen::screenMode = 0xFFFF;
uchar TScreen::screenWidth = 0;
uchar TScreen::screenHeight = 0;
uchar TScreen::Page = 0;
Boolean TScreen::hiResScreen = False;
Boolean TScreen::checkSnow = True;
long TScreen::screenBuffer = -1;
ushort TScreen::cursorLines = 0;
int TScreen_suspended = 1;
void SaveScreen();
void RestoreScreen();
void ScreenUpdate();
extern ushort user_mode;
#include <asm/io.h>
static inline
unsigned char I(unsigned char i)
{
outb(i,0x3b4);
return inb(0x3b5);
}
static inline
void O(unsigned char i,unsigned char b)
{
outb(i,0x3b4);
outb(b,0x3b5);
}
void TScreen::GetCursor(int &x,int &y)
{
if (dual_display)
{
}
else
{
TDisplay::GetCursor(x,y);
}
}
void TScreen::SetCursor(int x,int y)
{
if (dual_display || screenMode == 7)
{
unsigned short loc = y*80+x;
O(0x0e,loc >> 8);
O(0x0f,loc & 0xff);
}
else
{
TDisplay::SetCursor(x,y);
}
}
// static int was_blink = 0;
void setBlinkState();
void setIntenseState();
int getBlinkState();
TScreen::TScreen()
{
screenMode = startupMode = getCrtMode();
/*
* ESC ] Ps ND string NP
* ND can be any non-digit Character (it's discarded)
* NP can be any non-printing Character (it's discarded)
* string can be any ASCII printable string (max 511 characters)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -