more win32tty fixes

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.
This commit is contained in:
nethack.allison
2003-10-25 04:02:24 +00:00
parent b989a746a0
commit 58f322841d
8 changed files with 109 additions and 85 deletions

View 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 *));

View File

@@ -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 <process.h> /* Provides prototypes of exit(), spawn() */

View 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);
}

View File

@@ -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 */

View 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;
}

View 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;
}

View 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*/

View 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;
}