win32tty changes

1. Switch to low-level console routines for performance improvements.
2. Instead of moving the cursor around like a real tty, just track the
   destination coordinates of where the cursor should be, and
   defer the movement until user input is expected.

Credit to <Someone> for #2.
This commit is contained in:
nethack.allison
2003-10-05 23:00:05 +00:00
parent 4775dd3cbf
commit bc70857749
7 changed files with 149 additions and 227 deletions

View File

@@ -275,19 +275,8 @@ char *argv[];
# endif
#endif
if (!*plname) {
#ifdef WIN32CON
boolean revert = FALSE;
if (!iflags.rawio) {
set_output_mode(1);
revert = TRUE;
}
#endif
if (!*plname)
askname();
#ifdef WIN32CON
if (revert && iflags.rawio) set_output_mode(0);
#endif
}
plnamesuffix(); /* strip suffix from name; calls askname() */
/* again if suffix was whole name */
/* accepts any suffix */

View File

@@ -416,9 +416,6 @@ msmsg VA_DECL(const char *, fmt)
if (iflags.grmode)
gr_finish();
# endif
#ifdef WIN32CON
if (iflags.rawio) set_output_mode(0);
#endif
Vprintf(fmt, VA_ARGS);
flushout();
VA_END();

View File

@@ -75,9 +75,6 @@ error VA_DECL(const char *,s)
VA_INIT(s, const char *);
/* error() may get called before tty is initialized */
if (iflags.window_inited) end_screen();
#ifdef WIN32CON
if (iflags.rawio) set_output_mode(0);
#endif
putchar('\n');
Vprintf(s,VA_ARGS);
putchar('\n');

View File

@@ -103,9 +103,6 @@ getlock()
# if defined(MSDOS) && defined(NO_TERMS)
int grmode = iflags.grmode;
# endif
#ifdef WIN32CON
if (iflags.rawio) set_output_mode(0);
#endif
/* we ignore QUIT and INT at this point */
if (!lock_file(HLOCK, LOCKPREFIX, 10)) {
wait_synch();
@@ -263,9 +260,6 @@ gotlock:
# if defined(MSDOS) && defined(NO_TERMS)
if (grmode) gr_init();
# endif
#ifdef WIN32CON
if (!iflags.rawio) set_output_mode(1);
#endif
}
#endif /* PC_LOCKING */

View File

@@ -9,6 +9,7 @@
*/
#ifdef WIN32CON
#define LOW_LEVEL_OUTPUT
#define NEED_VARARGS /* Uses ... */
#include "hack.h"
#include "wintty.h"
@@ -32,7 +33,8 @@ int FDECL(process_keystroke, (INPUT_RECORD *, boolean *,
* SetConsoleCtrlHandler
* PeekConsoleInput
* ReadConsoleInput
* WriteConsole
* WriteConsoleOutputCharacter
* FillConsoleOutputAttribute
*/
/* Win32 Console handles for input and output */
@@ -110,21 +112,15 @@ static void NDECL(init_ttycolor);
#define MAX_OVERRIDES 256
unsigned char key_overrides[MAX_OVERRIDES];
#define DEFTEXTCOLOR ttycolors[7]
#ifdef TEXTCOLOR
#define DEFGLYPHBGRND (0)
#else
#define DEFGLYPHBGRND (0)
#endif
static char nullstr[] = "";
char erase_char,kill_char;
static char currentcolor = FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_BLUE;
static char noninvertedcurrentcolor = FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_BLUE;
static char currenthilite = 0;
static char currentbackground = 0;
static boolean colorchange = TRUE;
#define DEFTEXTCOLOR ttycolors[7]
static WORD background = 0;
static WORD foreground = (FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
static WORD attr = (FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
static DWORD ccount, acount;
static COORD cursor;
/*
* Called after returning from ! or ^Z
@@ -151,42 +147,11 @@ void
settty(s)
const char *s;
{
nocmov(ttyDisplay->curx, ttyDisplay->cury);
end_screen();
if(s) raw_print(s);
}
/*
* mode == 0 set processed console output mode.
* mode == 1 set raw console output mode (no control character expansion).
*/
void
set_output_mode(mode)
int mode;
{
static DWORD save_output_cmode = 0;
static boolean initmode = FALSE;
DWORD cmode, mask = ENABLE_PROCESSED_OUTPUT;
if (!initmode) {
/* fetch original output mode */
GetConsoleMode(hConOut,&save_output_cmode);
initmode = TRUE;
}
if (mode == 0) {
cmode = save_output_cmode;
/* Turn ON the settings specified in the mask */
cmode |= mask;
SetConsoleMode(hConOut,cmode);
iflags.rawio = 0;
} else {
cmode = save_output_cmode;
/* Turn OFF the settings specified in the mask */
cmode &= ~mask;
SetConsoleMode(hConOut,cmode);
iflags.rawio = 1;
}
}
/* called by init_nhwindows() and resume_nhwindows() */
void
setftty()
@@ -198,7 +163,6 @@ void
tty_startup(wid, hgt)
int *wid, *hgt;
{
/* int twid = origcsbi.dwSize.X; */
int twid = origcsbi.srWindow.Right - origcsbi.srWindow.Left + 1;
if (twid > 80) twid = 80;
@@ -253,7 +217,6 @@ DWORD ctrltype;
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
set_output_mode(0); /* Allow processed output */
getreturn_disable = TRUE;
#ifndef NOSAVEONHANGUP
hangup(0);
@@ -293,10 +256,11 @@ nttty_open()
(origcsbi.dwCursorPosition.Y == 0));
if ((origcsbi.dwSize.X <= 0) || (origcsbi.dwSize.Y <= 0))
GUILaunched = 0;
/* Obtain handles for the standard Console I/O devices */
hConIn = GetStdHandle(STD_INPUT_HANDLE);
hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
#if 0
/* Obtain handles for the standard Console I/O devices */
hConIn = CreateFile("CONIN$",
GENERIC_READ |GENERIC_WRITE,
FILE_SHARE_READ |FILE_SHARE_WRITE,
@@ -306,6 +270,7 @@ nttty_open()
FILE_SHARE_READ |FILE_SHARE_WRITE,
0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);
#endif
GetConsoleMode(hConIn,&cmode);
#ifdef NO_MOUSE_ALLOWED
mask = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT |
@@ -320,8 +285,6 @@ nttty_open()
cmode |= ENABLE_MOUSE_INPUT;
#endif
SetConsoleMode(hConIn,cmode);
set_output_mode(1); /* raw output mode; no tab expansion */
if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE)) {
/* Unable to set control handler */
cmode = 0; /* just to have a statement to break on for debugger */
@@ -376,6 +339,7 @@ tgetch()
int mod;
coord cc;
DWORD count;
nocmov(ttyDisplay->curx, ttyDisplay->cury);
return (program_state.done_hup) ?
'\033' :
pCheckInput(hConIn, &ir, &count, iflags.num_pad, 0, &mod, &cc);
@@ -388,6 +352,7 @@ int *x, *y, *mod;
int ch;
coord cc;
DWORD count;
nocmov(ttyDisplay->curx, ttyDisplay->cury);
ch = (program_state.done_hup) ?
'\033' :
pCheckInput(hConIn, &ir, &count, iflags.num_pad, 1, mod, &cc);
@@ -398,57 +363,51 @@ int *x, *y, *mod;
return ch;
}
void
nocmov(x, y)
int x,y;
{
ntcoord.X = x;
ntcoord.Y = y;
SetConsoleCursorPosition(hConOut,ntcoord);
}
void
cmov(x, y)
register int x, y;
{
ntcoord.X = x;
ntcoord.Y = y;
SetConsoleCursorPosition(hConOut,ntcoord);
ttyDisplay->cury = y;
ttyDisplay->curx = x;
ttyDisplay->cury = y;
cursor.X = x;
cursor.Y = y;
SetConsoleCursorPosition(hConOut, cursor);
}
void
xputc(c)
char c;
nocmov(x, y)
int x,y;
{
DWORD count;
cursor.Y = y;
cursor.X = x;
SetConsoleCursorPosition(hConOut, cursor);
}
switch(c) {
void
xputc(ch)
char ch;
{
cursor.X = ttyDisplay->curx;
cursor.Y = ttyDisplay->cury;
switch(ch) {
case '\n':
case '\r':
cmov(ttyDisplay->curx, ttyDisplay->cury);
return;
}
if (colorchange) {
SetConsoleTextAttribute(hConOut,
(currentcolor | currenthilite | currentbackground));
colorchange = FALSE;
}
WriteConsole(hConOut,&c,1,&count,0);
WriteConsoleOutputAttribute(hConOut,&attr,1,cursor,&acount);
WriteConsoleOutputCharacter(hConOut,&ch,1,cursor,&ccount);
}
void
xputs(s)
const char *s;
{
DWORD count;
if (colorchange) {
SetConsoleTextAttribute(hConOut,
(currentcolor | currenthilite | currentbackground));
colorchange = FALSE;
}
WriteConsole(hConOut,s,strlen(s),&count,0);
int slen = strlen(s);
cursor.X = ttyDisplay->curx;
cursor.Y = ttyDisplay->cury;
FillConsoleOutputAttribute(hConOut,attr,slen,cursor,&acount);
WriteConsoleOutputCharacter(hConOut,s,slen,cursor,&ccount);
}
/*
@@ -459,36 +418,32 @@ void
g_putch(in_ch)
int in_ch;
{
char ch = (char)in_ch;
DWORD count = 1;
int tcolor;
int bckgnd = currentbackground;
if (colorchange) {
tcolor = currentcolor | bckgnd | currenthilite;
SetConsoleTextAttribute(hConOut, tcolor);
}
WriteConsole(hConOut,&ch,1,&count,0);
colorchange = TRUE; /* force next output back to current nethack values */
return;
char ch = (char)in_ch;
cursor.X = ttyDisplay->curx;
cursor.Y = ttyDisplay->cury;
#if 0
switch(ch) {
case '\n':
case '\r':
cmov(cursor.X, cursor.Y);
return;
}
#endif
WriteConsoleOutputAttribute(hConOut,&attr,1,cursor,&acount);
WriteConsoleOutputCharacter(hConOut,&ch,1,cursor,&ccount);
}
void
cl_end()
{
DWORD count;
ntcoord.X = ttyDisplay->curx;
ntcoord.Y = ttyDisplay->cury;
FillConsoleOutputAttribute(hConOut, DEFTEXTCOLOR,
CO - ntcoord.X,ntcoord, &count);
ntcoord.X = ttyDisplay->curx;
ntcoord.Y = ttyDisplay->cury;
FillConsoleOutputCharacter(hConOut,' ',
CO - ntcoord.X,ntcoord,&count);
tty_curs(BASE_WINDOW, (int)ttyDisplay->curx+1,
(int)ttyDisplay->cury);
colorchange = TRUE;
int cx;
cursor.X = ttyDisplay->curx;
cursor.Y = ttyDisplay->cury;
cx = CO - cursor.X;
FillConsoleOutputAttribute(hConOut, DEFTEXTCOLOR, cx, cursor, &acount);
FillConsoleOutputCharacter(hConOut,' ', cx, cursor,&ccount);
tty_curs(BASE_WINDOW, (int)ttyDisplay->curx+1,
(int)ttyDisplay->cury);
}
@@ -505,13 +460,10 @@ clear_screen()
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
csbi.dwSize.X * csbi.dwSize.Y,
newcoord, &ccnt);
newcoord.X = 0;
newcoord.Y = 0;
FillConsoleOutputCharacter(hConOut,' ',
csbi.dwSize.X * csbi.dwSize.Y,
newcoord, &ccnt);
}
colorchange = TRUE;
home();
}
@@ -519,7 +471,7 @@ clear_screen()
void
home()
{
tty_curs(BASE_WINDOW, 1, 0);
cursor.X = cursor.Y = 0;
ttyDisplay->curx = ttyDisplay->cury = 0;
}
@@ -527,17 +479,34 @@ home()
void
backsp()
{
GetConsoleScreenBufferInfo(hConOut,&csbi);
if (csbi.dwCursorPosition.X > 0)
ntcoord.X = csbi.dwCursorPosition.X-1;
ntcoord.Y = csbi.dwCursorPosition.Y;
SetConsoleCursorPosition(hConOut,ntcoord);
/* colorchange shouldn't ever happen here but.. */
if (colorchange) {
SetConsoleTextAttribute(hConOut,
(currentcolor|currenthilite|currentbackground));
colorchange = FALSE;
GetConsoleScreenBufferInfo(hConOut,&csbi);
if (csbi.dwCursorPosition.X > 0)
ntcoord.X = csbi.dwCursorPosition.X-1;
ntcoord.Y = csbi.dwCursorPosition.Y;
SetConsoleCursorPosition(hConOut,ntcoord);
}
void
cl_eos()
{
register int cy = ttyDisplay->cury+1;
if (GetConsoleScreenBufferInfo(hConOut,&csbi)) {
DWORD ccnt;
COORD newcoord;
newcoord.X = 0;
newcoord.Y = ttyDisplay->cury;
FillConsoleOutputAttribute(hConOut,
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
csbi.dwSize.X * csbi.dwSize.Y - cy,
newcoord, &ccnt);
newcoord.X = 0;
newcoord.Y = ttyDisplay->cury;
FillConsoleOutputCharacter(hConOut,' ',
csbi.dwSize.X * csbi.dwSize.Y - cy,
newcoord, &ccnt);
}
tty_curs(BASE_WINDOW, (int)ttyDisplay->curx+1, (int)ttyDisplay->cury);
}
void
@@ -562,41 +531,6 @@ tty_delay_output()
}
}
void
cl_eos()
{
register int cy = ttyDisplay->cury+1;
#if 0
while(cy <= LI-2) {
cl_end();
xputc('\n');
cy++;
}
cl_end();
#else
if (GetConsoleScreenBufferInfo(hConOut,&csbi)) {
DWORD ccnt;
COORD newcoord;
newcoord.X = 0;
newcoord.Y = ttyDisplay->cury;
FillConsoleOutputAttribute(hConOut,
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
csbi.dwSize.X * csbi.dwSize.Y - cy,
newcoord, &ccnt);
newcoord.X = 0;
newcoord.Y = ttyDisplay->cury;
FillConsoleOutputCharacter(hConOut,' ',
csbi.dwSize.X * csbi.dwSize.Y - cy,
newcoord, &ccnt);
}
colorchange = TRUE;
#endif
tty_curs(BASE_WINDOW, (int)ttyDisplay->curx+1,
(int)ttyDisplay->cury);
}
# ifdef TEXTCOLOR
/*
* CLR_BLACK 0
@@ -661,111 +595,97 @@ has_color(int color)
}
void
term_start_attr(int attr)
term_start_attr(int attrib)
{
switch(attr){
switch(attrib){
case ATR_INVERSE:
if (iflags.wc_inverse) {
noninvertedcurrentcolor = currentcolor;
/* Suggestion by Lee Berger */
if ((currentcolor & (FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED)) ==
if ((foreground & (FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED)) ==
(FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED))
currentcolor = 0;
currentbackground = (BACKGROUND_RED|BACKGROUND_BLUE|BACKGROUND_GREEN);
colorchange = TRUE;
foreground &= ~(FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
background = (BACKGROUND_RED|BACKGROUND_BLUE|BACKGROUND_GREEN);
break;
} /* else */
}
/*FALLTHRU*/
case ATR_ULINE:
case ATR_BOLD:
case ATR_BLINK:
standoutbeg();
case ATR_BOLD:
foreground |= FOREGROUND_INTENSITY;
break;
default:
#ifdef DEBUG
impossible("term_start_attr: strange attribute %d", attr);
#endif
standoutend();
if (currentcolor == 0)
currentcolor = FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED;
currentbackground = 0;
foreground &= ~FOREGROUND_INTENSITY;
break;
}
attr = (foreground | background);
}
void
term_end_attr(int attr)
term_end_attr(int attrib)
{
switch(attr){
switch(attrib){
case ATR_INVERSE:
if (iflags.wc_inverse) {
if (currentcolor == 0 && noninvertedcurrentcolor != 0)
currentcolor = noninvertedcurrentcolor;
noninvertedcurrentcolor = 0;
currentbackground = 0;
colorchange = TRUE;
break;
} /* else */
/*FALLTHRU*/
if ((foreground & (FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED)) == 0)
foreground |= (FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
background = 0;
break;
case ATR_ULINE:
case ATR_BOLD:
case ATR_BLINK:
default:
standoutend();
if (currentcolor == 0)
currentcolor = FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED;
currentbackground = 0;
break;
case ATR_BOLD:
foreground &= ~FOREGROUND_INTENSITY;
break;
}
attr = (foreground | background);
}
void
term_end_raw_bold(void)
{
standoutend();
term_end_attr(ATR_BOLD);
}
void
term_start_raw_bold(void)
{
standoutbeg();
term_start_attr(ATR_BOLD);
}
void
term_start_color(int color)
{
# ifdef TEXTCOLOR
#ifdef TEXTCOLOR
if (color >= 0 && color < CLR_MAX) {
currentcolor = ttycolors[color];
colorchange = TRUE;
foreground = (background != 0 && (color == CLR_GRAY | color == CLR_WHITE)) ?
ttycolors[0] : ttycolors[color];
}
# endif
#else
foreground = DEFTEXTCOLOR;
#endif
attr = (foreground | background);
}
void
term_end_color(void)
{
# ifdef TEXTCOLOR
currentcolor = DEFTEXTCOLOR;
colorchange = TRUE;
# endif
#ifdef TEXTCOLOR
foreground = DEFTEXTCOLOR;
#endif
attr = (foreground | background);
}
void
standoutbeg()
{
currenthilite = FOREGROUND_INTENSITY;
colorchange = TRUE;
term_start_attr(ATR_BOLD);
}
void
standoutend()
{
currenthilite = 0;
colorchange = TRUE;
term_end_attr(ATR_BOLD);
}
#ifndef NO_MOUSE_ALLOWED
@@ -803,6 +723,7 @@ win32con_debug_keystrokes()
int ch;
xputs("\n");
while (!valid || ch != 27) {
nocmov(ttyDisplay->curx, ttyDisplay->cury);
ReadConsoleInput(hConIn,&ir,1,&count);
if ((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown)
ch = process_keystroke(&ir, &valid, iflags.num_pad, 1);

View File

@@ -272,15 +272,23 @@ topl_putsym(c)
ttyDisplay->curx = 0;
ttyDisplay->cury++;
cw->cury = ttyDisplay->cury;
#ifdef WIN32CON
(void) putchar(c);
#endif
break;
default:
if(ttyDisplay->curx == CO-1)
topl_putsym('\n'); /* 1 <= curx <= CO; avoid CO */
#ifdef WIN32CON
(void) putchar(c);
#endif
ttyDisplay->curx++;
}
cw->curx = ttyDisplay->curx;
if(cw->curx == 0) cl_end();
#ifndef WIN32CON
(void) putchar(c);
#endif
}
void

View File

@@ -688,6 +688,9 @@ tty_askname()
if (c == '\b' || c == '\177') {
if(ct) {
ct--;
#ifdef WIN32CON
ttyDisplay->curx--;
#endif
#if defined(MICRO) || defined(WIN32CON)
# if defined(WIN32CON) || defined(MSDOS)
backsp(); /* \b is visible on NT */
@@ -720,6 +723,9 @@ tty_askname()
(void) putchar(c);
#endif
plname[ct++] = c;
#ifdef WIN32CON
ttyDisplay->curx++;
#endif
}
}
plname[ct] = 0;
@@ -1217,8 +1223,13 @@ struct WinDesc *cw;
*/
term_start_attr(curr->attr);
for (n = 0, cp = curr->str;
#ifndef WIN32CON
*cp && (int) ++ttyDisplay->curx < (int) ttyDisplay->cols;
cp++, n++)
#else
*cp && (int) ttyDisplay->curx < (int) ttyDisplay->cols;
cp++, n++, ttyDisplay->curx++)
#endif
if (n == 2 && curr->identifier.a_void != 0 &&
curr->selected) {
if (curr->count == -1L)
@@ -1453,8 +1464,13 @@ struct WinDesc *cw;
}
term_start_attr(attr);
for (cp = &cw->data[i][1];
#ifndef WIN32CON
*cp && (int) ++ttyDisplay->curx < (int) ttyDisplay->cols;
cp++)
#else
*cp && (int) ttyDisplay->curx < (int) ttyDisplay->cols;
cp++, ttyDisplay->curx++)
#endif
(void) putchar(*cp);
term_end_attr(attr);
}