]> granicus.if.org Git - nethack/commitdiff
more win32tty fixes
authornethack.allison <nethack.allison>
Sat, 25 Oct 2003 04:02:24 +0000 (04:02 +0000)
committernethack.allison <nethack.allison>
Sat, 25 Oct 2003 04:02:24 +0000 (04:02 +0000)
There were still some significant startup message problems
with win32tty.

I've spent a lot of time in the debugger tracing through them all.
I think I've got them all worked out now, certainly the ones that
I was aware of.  There may be some I haven't discovered.
Testing welcomed of course!

This patch also attempts to diagnose the error where someone tries
to execute NetHack directly out of a zip file, and provide
them with a (hopefully) helpful message similar to what we
might end up telling them if they wrote in.  If you want
to test that part, you can comment out the line in the
Makefile that adds "dungeon" to nhdat, and delete the nhdat
in your binary and src directories, and "make install".
Then add the value of your TEMP environment variable as a
DATADIR statement in defaults.nh (here's mine):
DATADIR=C:\DOCUME~1\ALLISO~1\LOCALS~1\Temp
The diagnostic code engages if the game fails to open
dungeon. It then checks to see if it the game dir is the
TEMP directory for your system, and if so it prints the
message.

include/extern.h
include/ntconf.h
src/dungeon.c
src/end.c
sys/share/pcmain.c
sys/winnt/nttty.c
sys/winnt/winnt.c
win/tty/wintty.c

index d97dce46512bb801e70d18067ec5e6b0e5ac9132..eb492c3209962c8aadb0b3998a6b3ddfa520f7f6 100644 (file)
@@ -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 *));
index e6764fb5e4588c934e9e96560787a01c65dd1561..e5debb8ff2a9e88744aba95bbbca9847c7a358a3 100644 (file)
                         * 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 <process.h>   /* Provides prototypes of exit(), spawn()      */
index 1a5df39edb94afc1de0cd9b9485e36bdee594384..81ae23b119259b19e9abdbc48b64ab6650b7cb2a 100644 (file)
@@ -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);
        }
index 8a1ae69465a84bd33721fbe257603093b1f1dac1..c9331430b60ea55334b78c62dc53d3a9c09b3d1c 100644 (file)
--- 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 */
index 41a436d4a0bb46843783c3060dbaf482bd745a14..52f47045d21b00db75ad8b44839bf551555d4470 100644 (file)
@@ -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;
 }
index f46fea0e7e99f0d28b3554883c616066fc316725..f21d200bf571b634bb10900de4ea117a014a1699 100644 (file)
@@ -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;
 }
 
index e31bdc3740532355b4acb408ea32808cf863f6b3..13fde038084b66be68db30b9add622855afcfafa 100644 (file)
@@ -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*/
index 409bb3944824d26863d1e753ba866a3cda60819d..3a9134aebd3707f2482ace90bc9f031c70df48ea 100644 (file)
@@ -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;
 }