diff --git a/include/extern.h b/include/extern.h index d97dce465..eb492c320 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1333,7 +1333,6 @@ E void NDECL(lan_mail_terminate); E void NDECL(get_scr_size); E int NDECL(nttty_kbhit); E void NDECL(nttty_open); -E void NDECL(nttty_close); E void NDECL(nttty_rubout); E int NDECL(tgetch); E int FDECL(ntposkey,(int *, int *, int *)); diff --git a/include/ntconf.h b/include/ntconf.h index e6764fb5e..e5debb8ff 100644 --- a/include/ntconf.h +++ b/include/ntconf.h @@ -65,6 +65,12 @@ * objects being thrown when the hangup occurs. */ +/* Stuff to help the user with some common, yet significant errors */ +#define INTERJECT_PANIC 0 +#define INTERJECTION_TYPES (INTERJECT_PANIC + 1) +extern void FDECL(interject_assistance, (int,int,genericptr_t,genericptr_t)); +extern void FDECL(interject, (int)); + /* The following is needed for prototypes of certain functions */ #if defined(_MSC_VER) #include /* Provides prototypes of exit(), spawn() */ diff --git a/src/dungeon.c b/src/dungeon.c index 1a5df39ed..81ae23b11 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -659,6 +659,10 @@ init_dungeons() /* initialize the "dungeon" structs */ Strcat(tbuf, DLBFILE); # endif Strcat(tbuf, "\" file!"); +#endif +#ifdef WIN32 + interject_assistance(1, INTERJECT_PANIC, (genericptr_t)tbuf, + (genericptr_t)fqn_prefix[DATAPREFIX]); #endif panic(tbuf); } diff --git a/src/end.c b/src/end.c index 8a1ae6946..c9331430b 100644 --- a/src/end.c +++ b/src/end.c @@ -298,6 +298,9 @@ panic VA_DECL(const char *, str) raw_print(buf); paniclog("panic", buf); } +#ifdef WIN32 + interject(INTERJECT_PANIC); +#endif #if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE) || defined(WIN32)) if (wizard) NH_abort(); /* generate core dump */ diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 41a436d4a..52f47045d 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -379,6 +379,9 @@ char *argv[]; dlb_init(); display_gamewindows(); +#ifdef WIN32 + getreturn_enabled = TRUE; +#endif if ((fd = restore_saved_game()) >= 0) { #ifdef WIZARD @@ -436,9 +439,6 @@ not_recovered: #endif #ifdef OS2 gettty(); /* somehow ctrl-P gets turned back on during startup ... */ -#endif -#ifdef WIN32 - getreturn_enabled = TRUE; #endif return; } diff --git a/sys/winnt/nttty.c b/sys/winnt/nttty.c index f46fea0e7..f21d200bf 100644 --- a/sys/winnt/nttty.c +++ b/sys/winnt/nttty.c @@ -112,6 +112,7 @@ int ttycolors[CLR_MAX]; # ifdef TEXTCOLOR static void NDECL(init_ttycolor); # endif +static void NDECL(really_move_cursor); #define MAX_OVERRIDES 256 unsigned char key_overrides[MAX_OVERRIDES]; @@ -124,7 +125,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; +static COORD cursor = {0,0}; /* * Called after returning from ! or ^Z @@ -151,7 +152,7 @@ void settty(s) const char *s; { - nocmov(ttyDisplay->curx, ttyDisplay->cury); + cmov(ttyDisplay->curx, ttyDisplay->cury); end_screen(); if(s) raw_print(s); } @@ -292,6 +293,8 @@ nttty_open() cmode = 0; /* just to have a statement to break on for debugger */ } get_scr_size(); + cursor.X = cursor.Y = 0; + really_move_cursor(); } int process_keystroke(ir, valid, numberpad, portdebug) @@ -319,8 +322,8 @@ get_scr_size() { GetConsoleScreenBufferInfo(hConOut, &csbi); - LI = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; - CO = csbi.srWindow.Right - csbi.srWindow.Left + 1; + LI = csbi.srWindow.Bottom - (csbi.srWindow.Top + 1); + CO = csbi.srWindow.Right - (csbi.srWindow.Left + 1); if ( (LI < 25) || (CO < 80) ) { COORD newcoord; @@ -341,7 +344,7 @@ tgetch() int mod; coord cc; DWORD count; - if (iflags.window_inited) nocmov(ttyDisplay->curx, ttyDisplay->cury); + really_move_cursor(); return (program_state.done_hup) ? '\033' : pCheckInput(hConIn, &ir, &count, iflags.num_pad, 0, &mod, &cc); @@ -354,7 +357,7 @@ int *x, *y, *mod; int ch; coord cc; DWORD count; - nocmov(ttyDisplay->curx, ttyDisplay->cury); + really_move_cursor(); ch = (program_state.done_hup) ? '\033' : pCheckInput(hConIn, &ir, &count, iflags.num_pad, 1, mod, &cc); @@ -365,15 +368,20 @@ int *x, *y, *mod; return ch; } +static void +really_move_cursor() +{ + SetConsoleCursorPosition(hConOut, cursor); +} + void cmov(x, y) register int x, y; { - ttyDisplay->curx = x; - ttyDisplay->cury = y; cursor.X = x; cursor.Y = y; - SetConsoleCursorPosition(hConOut, cursor); + ttyDisplay->curx = x; + ttyDisplay->cury = y; } void @@ -382,34 +390,37 @@ int x,y; { cursor.Y = y; cursor.X = x; - SetConsoleCursorPosition(hConOut, cursor); + ttyDisplay->curx = x; + ttyDisplay->cury = y; } void xputc(ch) char ch; { - cursor.X = ttyDisplay->curx; - cursor.Y = ttyDisplay->cury; switch(ch) { case '\n': + cursor.Y++; + /* fall through */ case '\r': - cmov(cursor.X, cursor.Y); - return; + cursor.X = 0; + cmov(cursor.X, cursor.Y); + return; } WriteConsoleOutputAttribute(hConOut,&attr,1,cursor,&acount); WriteConsoleOutputCharacter(hConOut,&ch,1,cursor,&ccount); + cursor.X++; + cmov(cursor.X, cursor.Y); } void xputs(s) const char *s; { - int slen = strlen(s); - cursor.X = ttyDisplay->curx; - cursor.Y = ttyDisplay->cury; - FillConsoleOutputAttribute(hConOut,attr,slen,cursor,&acount); - WriteConsoleOutputCharacter(hConOut,s,slen,cursor,&ccount); + int k, slen = strlen(s); + if (s) + for (k=0; k < slen && s[k]; ++k) + xputc(s[k]); } @@ -422,16 +433,9 @@ g_putch(in_ch) int in_ch; { 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); } @@ -440,8 +444,6 @@ 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); @@ -482,11 +484,9 @@ 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); + cursor.X--; + xputc(' '); + cursor.X--; } void @@ -877,59 +877,18 @@ load_keyboard_handler() } } -static COORD msmsgcursor = {0,4}; /* avoid copyright notice */ - -void -nttty_close() -{ - msmsgcursor.X = 0; - msmsgcursor.Y = 0; -#if 0 - if (GetConsoleScreenBufferInfo(hConOut,&csbi)) { - DWORD ccnt; - FillConsoleOutputAttribute(hConOut, - FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, - csbi.dwSize.X * csbi.dwSize.Y, - msmsgcursor, &ccnt); - FillConsoleOutputCharacter(hConOut,' ', - csbi.dwSize.X * csbi.dwSize.Y, - msmsgcursor, &ccnt); - } -#endif -} - /* this is used when window system isn't initialized yet */ void msmsg VA_DECL(const char *, fmt) - char buf[BUFSZ]; - int slen, k, ac, cc; + char buf[ROWNO * COLNO]; /* worst case scenario */ VA_START(fmt); VA_INIT(fmt, const char *); Vsprintf(buf, fmt, VA_ARGS); VA_END(); - slen = strlen(buf); - SetConsoleCursorPosition(hConOut, msmsgcursor); - for (k = 0; k < slen; ++k) { - switch(buf[k]) { - case '\n': - msmsgcursor.Y = msmsgcursor.Y++ % 24; - msmsgcursor.X = 0; - break; - case '\r': - msmsgcursor.Y = 0; - msmsgcursor.X = 0; - break; - default: - FillConsoleOutputAttribute(hConOut,attr,1, - msmsgcursor,&ac); - WriteConsoleOutputCharacter(hConOut,&buf[k],1, - msmsgcursor,&cc); - msmsgcursor.X++; - } - SetConsoleCursorPosition(hConOut, msmsgcursor); - } + xputs(buf); + really_move_cursor(); return; } diff --git a/sys/winnt/winnt.c b/sys/winnt/winnt.c index e31bdc374..13fde0380 100644 --- a/sys/winnt/winnt.c +++ b/sys/winnt/winnt.c @@ -259,6 +259,62 @@ void win32_abort() #endif abort(); } + +static char interjection_buf[INTERJECTION_TYPES][1024]; +static int interjection[INTERJECTION_TYPES]; + +void +interject_assistance(num, interjection_type, ptr1, ptr2) +int num; +int interjection_type; +genericptr_t ptr1; +genericptr_t ptr2; +{ + switch(num) { + case 1: { + char *panicmsg = (char *)ptr1; + char *datadir = (char *)ptr2; + char *tempdir = nh_getenv("TEMP"); + interjection_type = INTERJECT_PANIC; + interjection[INTERJECT_PANIC] = 1; + /* + * ptr1 = the panic message about to be delivered. + * ptr2 = the directory prefix of the dungeon file + * that failed to open. + * Check to see if datadir matches tempdir or a + * common windows temp location. If it does, inform + * the user that they are probably trying to run the + * game from within their unzip utility, so the required + * files really don't exist at the location. Instruct + * them to unpack them first. + */ + if (panicmsg && datadir) { + if (!strncmpi(datadir, "C:\\WINDOWS\\TEMP", 15) || + 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" + "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" + "If that is not the situation, you are encouraged to\n" + "report the error as shown above.\n\n", 1023); + } + } + } + break; + } +} + +void +interject(interjection_type) +int interjection_type; +{ + if (interjection_type >= 0 && interjection_type < INTERJECTION_TYPES) + msmsg(interjection_buf[interjection_type]); +} #endif /* WIN32 */ /*winnt.c*/ diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 409bb3944..3a9134aeb 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -793,9 +793,6 @@ tty_exit_nhwindows(str) } #ifndef NO_TERMS /*(until this gets added to the window interface)*/ tty_shutdown(); /* cleanup termcap/terminfo/whatever */ -#endif -#ifdef WIN32CON - nttty_close(); #endif iflags.window_inited = 0; }