Additional changes to xputc_core() and early_raw_print() to manage
the cursor position correctly. This is needed to handle raw printing correctly. Added check for when we might be running off the bottom of the screen when handling msmsg(). Added runtime checks to keep cursor always within bounds.
This commit is contained in:
+78
-39
@@ -458,6 +458,15 @@ int *x, *y, *mod;
|
|||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_console_cursor(int x, int y)
|
||||||
|
{
|
||||||
|
ntassert(x >= 0 && x < console.width);
|
||||||
|
ntassert(y >= 0 && y < console.height);
|
||||||
|
|
||||||
|
console.cursor.X = max(0, min(console.width - 1, x));
|
||||||
|
console.cursor.Y = max(0, min(console.height - 1, y));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
really_move_cursor()
|
really_move_cursor()
|
||||||
{
|
{
|
||||||
@@ -474,10 +483,9 @@ really_move_cursor()
|
|||||||
(void) SetConsoleTitle(newtitle);
|
(void) SetConsoleTitle(newtitle);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (ttyDisplay) {
|
if (ttyDisplay)
|
||||||
console.cursor.X = ttyDisplay->curx;
|
set_console_cursor(ttyDisplay->curx, ttyDisplay->cury);
|
||||||
console.cursor.Y = ttyDisplay->cury;
|
|
||||||
}
|
|
||||||
back_buffer_flip();
|
back_buffer_flip();
|
||||||
SetConsoleCursorPosition(console.hConOut, console.cursor);
|
SetConsoleCursorPosition(console.hConOut, console.cursor);
|
||||||
}
|
}
|
||||||
@@ -488,26 +496,25 @@ register int x, y;
|
|||||||
{
|
{
|
||||||
ttyDisplay->cury = y;
|
ttyDisplay->cury = y;
|
||||||
ttyDisplay->curx = x;
|
ttyDisplay->curx = x;
|
||||||
console.cursor.X = x;
|
|
||||||
console.cursor.Y = y;
|
set_console_cursor(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nocmov(x, y)
|
nocmov(x, y)
|
||||||
int x, y;
|
int x, y;
|
||||||
{
|
{
|
||||||
console.cursor.X = x;
|
|
||||||
console.cursor.Y = y;
|
|
||||||
ttyDisplay->curx = x;
|
ttyDisplay->curx = x;
|
||||||
ttyDisplay->cury = y;
|
ttyDisplay->cury = y;
|
||||||
|
|
||||||
|
set_console_cursor(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xputc(ch)
|
xputc(ch)
|
||||||
char ch;
|
char ch;
|
||||||
{
|
{
|
||||||
console.cursor.X = ttyDisplay->curx;
|
set_console_cursor(ttyDisplay->curx, ttyDisplay->cury);
|
||||||
console.cursor.Y = ttyDisplay->cury;
|
|
||||||
xputc_core(ch);
|
xputc_core(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,10 +525,8 @@ const char *s;
|
|||||||
int k;
|
int k;
|
||||||
int slen = strlen(s);
|
int slen = strlen(s);
|
||||||
|
|
||||||
if (ttyDisplay) {
|
if (ttyDisplay)
|
||||||
console.cursor.X = ttyDisplay->curx;
|
set_console_cursor(ttyDisplay->curx, ttyDisplay->cury);
|
||||||
console.cursor.Y = ttyDisplay->cury;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s) {
|
if (s) {
|
||||||
for (k = 0; k < slen && s[k]; ++k)
|
for (k = 0; k < slen && s[k]; ++k)
|
||||||
@@ -537,6 +542,9 @@ void
|
|||||||
xputc_core(ch)
|
xputc_core(ch)
|
||||||
char ch;
|
char ch;
|
||||||
{
|
{
|
||||||
|
ntassert(console.cursor.X >= 0 && console.cursor.X < console.width);
|
||||||
|
ntassert(console.cursor.Y >= 0 && console.cursor.Y < console.height);
|
||||||
|
|
||||||
boolean inverse = FALSE;
|
boolean inverse = FALSE;
|
||||||
cell_t cell;
|
cell_t cell;
|
||||||
|
|
||||||
@@ -549,7 +557,12 @@ char ch;
|
|||||||
console.cursor.X = 1;
|
console.cursor.X = 1;
|
||||||
break;
|
break;
|
||||||
case '\b':
|
case '\b':
|
||||||
console.cursor.X--;
|
if (console.cursor.X > 1) {
|
||||||
|
console.cursor.X--;
|
||||||
|
} else if(console.cursor.Y > 0) {
|
||||||
|
console.cursor.X = console.width - 1;
|
||||||
|
console.cursor.Y--;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
inverse = (console.current_nhattr[ATR_INVERSE] && iflags.wc_inverse);
|
inverse = (console.current_nhattr[ATR_INVERSE] && iflags.wc_inverse);
|
||||||
@@ -565,14 +578,18 @@ char ch;
|
|||||||
|
|
||||||
buffer_write(console.back_buffer, &cell, console.cursor);
|
buffer_write(console.back_buffer, &cell, console.cursor);
|
||||||
|
|
||||||
console.cursor.X++;
|
if (console.cursor.X == console.width - 1) {
|
||||||
|
if (console.cursor.Y < console.height - 1) {
|
||||||
if (console.cursor.X == console.width) {
|
console.cursor.X = 1;
|
||||||
console.cursor.X = 0;
|
|
||||||
if (console.cursor.Y < console.height - 1)
|
|
||||||
console.cursor.Y++;
|
console.cursor.Y++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.cursor.X++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ntassert(console.cursor.X >= 0 && console.cursor.X < console.width);
|
||||||
|
ntassert(console.cursor.Y >= 0 && console.cursor.Y < console.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -623,8 +640,7 @@ int in_ch;
|
|||||||
boolean inverse = FALSE;
|
boolean inverse = FALSE;
|
||||||
unsigned char ch = (unsigned char) in_ch;
|
unsigned char ch = (unsigned char) in_ch;
|
||||||
|
|
||||||
console.cursor.X = ttyDisplay->curx;
|
set_console_cursor(ttyDisplay->curx, ttyDisplay->cury);
|
||||||
console.cursor.Y = ttyDisplay->cury;
|
|
||||||
|
|
||||||
inverse = (console.current_nhattr[ATR_INVERSE] && iflags.wc_inverse);
|
inverse = (console.current_nhattr[ATR_INVERSE] && iflags.wc_inverse);
|
||||||
console.attr = (console.current_nhattr[ATR_INVERSE] && iflags.wc_inverse) ?
|
console.attr = (console.current_nhattr[ATR_INVERSE] && iflags.wc_inverse) ?
|
||||||
@@ -644,8 +660,7 @@ int in_ch;
|
|||||||
void
|
void
|
||||||
cl_end()
|
cl_end()
|
||||||
{
|
{
|
||||||
console.cursor.X = ttyDisplay->curx;
|
set_console_cursor(ttyDisplay->curx, ttyDisplay->cury);
|
||||||
console.cursor.Y = ttyDisplay->cury;
|
|
||||||
buffer_clear_to_end_of_line(console.back_buffer, console.cursor.X,
|
buffer_clear_to_end_of_line(console.back_buffer, console.cursor.X,
|
||||||
console.cursor.Y);
|
console.cursor.Y);
|
||||||
tty_curs(BASE_WINDOW, (int) ttyDisplay->curx + 1, (int) ttyDisplay->cury);
|
tty_curs(BASE_WINDOW, (int) ttyDisplay->curx + 1, (int) ttyDisplay->cury);
|
||||||
@@ -667,15 +682,14 @@ clear_screen()
|
|||||||
void
|
void
|
||||||
home()
|
home()
|
||||||
{
|
{
|
||||||
console.cursor.X = console.cursor.Y = 0;
|
|
||||||
ttyDisplay->curx = ttyDisplay->cury = 0;
|
ttyDisplay->curx = ttyDisplay->cury = 0;
|
||||||
|
set_console_cursor(ttyDisplay->curx, ttyDisplay->cury);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
backsp()
|
backsp()
|
||||||
{
|
{
|
||||||
console.cursor.X = ttyDisplay->curx;
|
set_console_cursor(ttyDisplay->curx, ttyDisplay->cury);
|
||||||
console.cursor.Y = ttyDisplay->cury;
|
|
||||||
xputc_core('\b');
|
xputc_core('\b');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1082,6 +1096,17 @@ VA_DECL(const char *, fmt)
|
|||||||
if(!init_ttycolor_completed)
|
if(!init_ttycolor_completed)
|
||||||
init_ttycolor();
|
init_ttycolor();
|
||||||
|
|
||||||
|
/* if we have generated too many messages ... ask the user to
|
||||||
|
* confirm and then clear.
|
||||||
|
*/
|
||||||
|
if (console.cursor.Y > console.height - 4) {
|
||||||
|
xputs("Hit <Enter> to continue.");
|
||||||
|
while (pgetchar() != '\n')
|
||||||
|
;
|
||||||
|
raw_clear_screen();
|
||||||
|
set_console_cursor(1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
xputs(buf);
|
xputs(buf);
|
||||||
if (ttyDisplay)
|
if (ttyDisplay)
|
||||||
curs(BASE_WINDOW, console.cursor.X + 1, console.cursor.Y);
|
curs(BASE_WINDOW, console.cursor.X + 1, console.cursor.Y);
|
||||||
@@ -1714,35 +1739,49 @@ void early_raw_print(const char *s)
|
|||||||
if (console.hConOut == NULL)
|
if (console.hConOut == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ntassert(console.cursor.X >= 0 && console.cursor.X < console.width);
|
||||||
|
ntassert(console.cursor.Y >= 0 && console.cursor.Y < console.height);
|
||||||
|
|
||||||
WORD attribute = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE;
|
WORD attribute = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE;
|
||||||
DWORD unused;
|
DWORD unused;
|
||||||
|
|
||||||
while (*s != '\0') {
|
while (*s != '\0') {
|
||||||
switch (*s) {
|
switch (*s) {
|
||||||
case '\n':
|
case '\n':
|
||||||
console.cursor.Y++;
|
if (console.cursor.Y < console.height - 1)
|
||||||
|
console.cursor.Y++;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case '\r':
|
case '\r':
|
||||||
console.cursor.X = 0;
|
console.cursor.X = 1;
|
||||||
break;
|
break;
|
||||||
case '\b':
|
case '\b':
|
||||||
console.cursor.X--;
|
if (console.cursor.X > 1) {
|
||||||
|
console.cursor.X--;
|
||||||
|
} else if(console.cursor.Y > 0) {
|
||||||
|
console.cursor.X = console.width - 1;
|
||||||
|
console.cursor.Y--;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WriteConsoleOutputAttribute(console.hConOut, &attribute,
|
WriteConsoleOutputAttribute(console.hConOut, &attribute,
|
||||||
1, console.cursor, &unused);
|
1, console.cursor, &unused);
|
||||||
WriteConsoleOutputCharacterA(console.hConOut, s,
|
WriteConsoleOutputCharacterA(console.hConOut, s,
|
||||||
1, console.cursor, &unused);
|
1, console.cursor, &unused);
|
||||||
console.cursor.X++;
|
if (console.cursor.X == console.width - 1) {
|
||||||
|
if (console.cursor.Y < console.height - 1) {
|
||||||
if (console.cursor.X == console.width) {
|
console.cursor.X = 1;
|
||||||
console.cursor.Y++;
|
console.cursor.Y++;
|
||||||
console.cursor.X = 0;
|
}
|
||||||
|
} else {
|
||||||
|
console.cursor.X++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ntassert(console.cursor.X >= 0 && console.cursor.X < console.width);
|
||||||
|
ntassert(console.cursor.Y >= 0 && console.cursor.Y < console.height);
|
||||||
|
|
||||||
SetConsoleCursorPosition(console.hConOut, console.cursor);
|
SetConsoleCursorPosition(console.hConOut, console.cursor);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1776,9 +1815,6 @@ void nethack_enter_nttty()
|
|||||||
/* set up state needed by early_raw_print() */
|
/* set up state needed by early_raw_print() */
|
||||||
windowprocs.win_raw_print = early_raw_print;
|
windowprocs.win_raw_print = early_raw_print;
|
||||||
|
|
||||||
console.cursor.X = 0;
|
|
||||||
console.cursor.Y = 0;
|
|
||||||
|
|
||||||
console.hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
console.hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
ntassert(console.hConOut != NULL); // NOTE: this assert will not print
|
ntassert(console.hConOut != NULL); // NOTE: this assert will not print
|
||||||
|
|
||||||
@@ -1802,9 +1838,11 @@ void nethack_enter_nttty()
|
|||||||
|
|
||||||
console.buffer_size = console.width * console.height;
|
console.buffer_size = console.width * console.height;
|
||||||
|
|
||||||
|
|
||||||
/* clear the entire console buffer */
|
/* clear the entire console buffer */
|
||||||
int size = console.origcsbi.dwSize.X * console.origcsbi.dwSize.Y;
|
int size = console.origcsbi.dwSize.X * console.origcsbi.dwSize.Y;
|
||||||
DWORD unused;
|
DWORD unused;
|
||||||
|
set_console_cursor(0, 0);
|
||||||
FillConsoleOutputAttribute(
|
FillConsoleOutputAttribute(
|
||||||
console.hConOut, CONSOLE_CLEAR_ATTRIBUTE,
|
console.hConOut, CONSOLE_CLEAR_ATTRIBUTE,
|
||||||
size, console.cursor, &unused);
|
size, console.cursor, &unused);
|
||||||
@@ -1813,9 +1851,10 @@ void nethack_enter_nttty()
|
|||||||
console.hConOut, CONSOLE_CLEAR_CHARACTER,
|
console.hConOut, CONSOLE_CLEAR_CHARACTER,
|
||||||
size, console.cursor, &unused);
|
size, console.cursor, &unused);
|
||||||
|
|
||||||
|
set_console_cursor(1, 0);
|
||||||
SetConsoleCursorPosition(console.hConOut, console.cursor);
|
SetConsoleCursorPosition(console.hConOut, console.cursor);
|
||||||
|
|
||||||
/* At this point early_raw_print will output */
|
/* At this point early_raw_print will work */
|
||||||
|
|
||||||
console.hConIn = GetStdHandle(STD_INPUT_HANDLE);
|
console.hConIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
ntassert(console.hConIn != NULL);
|
ntassert(console.hConIn != NULL);
|
||||||
|
|||||||
Reference in New Issue
Block a user