diff --git a/include/extern.h b/include/extern.h index 64cbb2803..4bf999483 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1338,6 +1338,7 @@ E void NDECL(nttty_rubout); E int NDECL(tgetch); E int FDECL(ntposkey,(int *, int *, int *)); E void FDECL(set_output_mode, (int)); +E void NDECL(synch_cursor); #endif /* ### o_init.c ### */ diff --git a/sys/share/pcsys.c b/sys/share/pcsys.c index cbeaca795..b67661cc0 100644 --- a/sys/share/pcsys.c +++ b/sys/share/pcsys.c @@ -490,10 +490,6 @@ void nethack_exit(code) int code; { msexit(); -#ifdef MTHREAD_VIEW - if (iflags.mthreaded) nh_thread_exit(code); /* no return from this */ - else -#endif exit(code); } @@ -536,8 +532,9 @@ static void msexit() * not vanish instantly after being created. * GUILaunched is defined and set in nttty.c. */ - + synch_cursor(); if (GUILaunched) getreturn("to end"); + synch_cursor(); #endif return; } diff --git a/sys/share/pcunix.c b/sys/share/pcunix.c index 2aff2c8cd..85e1a7e65 100644 --- a/sys/share/pcunix.c +++ b/sys/share/pcunix.c @@ -5,6 +5,7 @@ /* This file collects some Unix dependencies; pager.c contains some more */ #include "hack.h" +#include "wintty.h" #include #if defined(WIN32) || defined(MSDOS) @@ -174,13 +175,7 @@ getlock() # endif while ((ci=nhgetch()) != '\n') { if (ct > 0) { -# if defined(WIN32CON) - backsp(); /* \b is visible on NT */ - (void) putchar(' '); - backsp(); -# else msmsg("\b \b"); -# endif ct = 0; c = 'n'; } diff --git a/sys/winnt/nttty.c b/sys/winnt/nttty.c index f21d200bf..1f033b48d 100644 --- a/sys/winnt/nttty.c +++ b/sys/winnt/nttty.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)nttty.c 3.4 $Date$ */ + /* SCCS Id: @(#)nttty.c 3.4 $Date$ */ /* Copyright (c) NetHack PC Development Team 1993 */ /* NetHack may be freely redistributed. See license for details. */ @@ -58,6 +58,10 @@ INPUT_RECORD ir; int GUILaunched; static BOOL FDECL(CtrlHandler, (DWORD)); +#ifdef PORT_DEBUG +static boolean display_cursor_info = TRUE; +#endif + extern boolean getreturn_enabled; /* from sys/share/pcsys.c */ /* dynamic keystroke handling .DLL support */ @@ -192,6 +196,7 @@ void tty_end_screen() { clear_screen(); + really_move_cursor(); if (GetConsoleScreenBufferInfo(hConOut,&csbi)) { DWORD ccnt; @@ -371,6 +376,23 @@ int *x, *y, *mod; static void really_move_cursor() { +#if defined(PORT_DEBUG) && defined(WIZARD) + char oldtitle[BUFSZ], newtitle[BUFSZ]; + if (display_cursor_info && wizard) { + oldtitle[0] = '\0'; + if (GetConsoleTitle(oldtitle, BUFSZ)) { + oldtitle[39] = '\0'; + } + Sprintf(newtitle, "%-55s tty=(%02d,%02d) nttty=(%02d,%02d)", + oldtitle, ttyDisplay->curx, ttyDisplay->cury, + cursor.X, cursor.Y); + (void)SetConsoleTitle(newtitle); + } +#endif + if (ttyDisplay) { + cursor.X = ttyDisplay->curx; + cursor.Y = ttyDisplay->cury; + } SetConsoleCursorPosition(hConOut, cursor); } @@ -378,24 +400,24 @@ void cmov(x, y) register int x, y; { + ttyDisplay->cury = y; + ttyDisplay->curx = x; cursor.X = x; cursor.Y = y; - ttyDisplay->curx = x; - ttyDisplay->cury = y; } void nocmov(x, y) int x,y; { - cursor.Y = y; cursor.X = x; + cursor.Y = y; ttyDisplay->curx = x; ttyDisplay->cury = y; } void -xputc(ch) +xputc_core(ch) char ch; { switch(ch) { @@ -403,29 +425,55 @@ char ch; cursor.Y++; /* fall through */ case '\r': - cursor.X = 0; - cmov(cursor.X, cursor.Y); - return; + cursor.X = 1; + break; + case '\b': + cursor.X--; + ch = ' '; + WriteConsoleOutputAttribute(hConOut,&attr,1, + cursor,&acount); + WriteConsoleOutputCharacter(hConOut,&ch,1, + cursor,&ccount); + break; + default: + WriteConsoleOutputAttribute(hConOut,&attr,1, + cursor,&acount); + WriteConsoleOutputCharacter(hConOut,&ch,1, + cursor,&ccount); + cursor.X++; } - WriteConsoleOutputAttribute(hConOut,&attr,1,cursor,&acount); - WriteConsoleOutputCharacter(hConOut,&ch,1,cursor,&ccount); - cursor.X++; - cmov(cursor.X, cursor.Y); +} + +void +xputc(ch) +char ch; +{ + cursor.X = ttyDisplay->curx; + cursor.Y = ttyDisplay->cury; + xputc_core(ch); } void xputs(s) const char *s; { - int k, slen = strlen(s); - if (s) + int k; + int slen = strlen(s); + + if (ttyDisplay) { + cursor.X = ttyDisplay->curx; + cursor.Y = ttyDisplay->cury; + } + + if (s) { for (k=0; k < slen && s[k]; ++k) - xputc(s[k]); + xputc_core(s[k]); + } } /* - * Overrides winntty.c function of the same name + * Overrides wintty.c function of the same name * for win32. It is used for glyphs only, not text. */ void @@ -444,6 +492,8 @@ void cl_end() { 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); @@ -484,27 +534,25 @@ home() void backsp() { - cursor.X--; - xputc(' '); - cursor.X--; + cursor.X = ttyDisplay->curx; + cursor.Y = ttyDisplay->cury; + xputc_core('\b'); } void cl_eos() { - register int cy = ttyDisplay->cury+1; + int cy = ttyDisplay->cury+1; if (GetConsoleScreenBufferInfo(hConOut,&csbi)) { DWORD ccnt; COORD newcoord; - newcoord.X = 0; + newcoord.X = ttyDisplay->curx; 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); @@ -762,6 +810,11 @@ win32con_handler_info() (void)doredraw(); } } + +void win32con_toggle_cursor_info() +{ + display_cursor_info = !display_cursor_info; +} #endif void @@ -877,19 +930,41 @@ load_keyboard_handler() } } -/* this is used when window system isn't initialized yet */ +/* this is used as a printf() replacement when the window + * system isn't initialized yet + */ void msmsg VA_DECL(const char *, fmt) char buf[ROWNO * COLNO]; /* worst case scenario */ - VA_START(fmt); VA_INIT(fmt, const char *); Vsprintf(buf, fmt, VA_ARGS); VA_END(); - xputs(buf); - really_move_cursor(); + curs(BASE_WINDOW, cursor.X+1, cursor.Y); return; } +/* fatal error */ +/*VARARGS1*/ +void +error VA_DECL(const char *,s) + char buf[BUFSZ]; + VA_START(s); + VA_INIT(s, const char *); + /* error() may get called before tty is initialized */ + if (iflags.window_inited) end_screen(); + buf[0] = '\n'; + (void) vsprintf(&buf[1], s, VA_ARGS); + VA_END(); + msmsg(buf); + really_move_cursor(); + exit(EXIT_FAILURE); +} + +void +synch_cursor() +{ + really_move_cursor(); +} #endif /* WIN32CON */ diff --git a/sys/winnt/winnt.c b/sys/winnt/winnt.c index 2c614a0be..d51a581e9 100644 --- a/sys/winnt/winnt.c +++ b/sys/winnt/winnt.c @@ -17,7 +17,9 @@ #endif #include #include "win32api.h" - +#ifdef WIN32CON +#include "wintty.h" +#endif #ifdef WIN32 @@ -195,21 +197,22 @@ return &szFullPath[0]; } # endif - +#ifndef WIN32CON /* fatal error */ /*VARARGS1*/ void error VA_DECL(const char *,s) + char buf[BUFSZ]; VA_START(s); VA_INIT(s, const char *); /* error() may get called before tty is initialized */ if (iflags.window_inited) end_screen(); if (!strncmpi(windowprocs.name, "tty", 3)) { - putchar('\n'); - Vprintf(s,VA_ARGS); - putchar('\n'); + buf[0] = '\n'; + (void) vsprintf(&buf[1], s, VA_ARGS); + Strcat(buf, "\n"); + msmsg(buf); } else { - char buf[BUFSZ]; (void) vsprintf(buf, s, VA_ARGS); Strcat(buf, "\n"); raw_printf(buf); @@ -217,6 +220,8 @@ error VA_DECL(const char *,s) VA_END(); exit(EXIT_FAILURE); } +#endif + void Delay(int ms) { (void)Sleep(ms); @@ -292,9 +297,9 @@ genericptr_t ptr2; strstri(datadir, "TEMP") || (tempdir && strstri(datadir, tempdir))) { (void)strncpy(interjection_buf[INTERJECT_PANIC], - "\nThe nature of the error seems to indicate that you may\n" - "be attempting to execute the game by double-clicking on \n" - "it from within the download distribution zip file.\n\n" + "\nOne common cause of this error is attempting to execute\n" + "the game by double-clicking on it while it is displayed\n" + "inside an unzip utility.\n\n" "You have to unzip the contents of the zip file into a\n" "folder on your system, and then run \"NetHack.exe\" or \n" "\"NetHackW.exe\" from there.\n\n" diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 3a9134aeb..26ce38882 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -147,8 +147,8 @@ boolean GFlag = FALSE; boolean HE_resets_AS; /* see termcap.c */ #endif -#ifdef MICRO -static char to_continue[] = "to continue"; +#if defined(MICRO) || defined(WIN32CON) +static const char to_continue[] = "to continue"; #define getret() getreturn(to_continue) #else STATIC_DCL void NDECL(getret); @@ -741,7 +741,7 @@ tty_get_nh_event() return; } -#ifndef MICRO +#if !defined(MICRO) && !defined(WIN32CON) STATIC_OVL void getret() {