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:
@@ -1333,7 +1333,6 @@ E void NDECL(lan_mail_terminate);
|
|||||||
E void NDECL(get_scr_size);
|
E void NDECL(get_scr_size);
|
||||||
E int NDECL(nttty_kbhit);
|
E int NDECL(nttty_kbhit);
|
||||||
E void NDECL(nttty_open);
|
E void NDECL(nttty_open);
|
||||||
E void NDECL(nttty_close);
|
|
||||||
E void NDECL(nttty_rubout);
|
E void NDECL(nttty_rubout);
|
||||||
E int NDECL(tgetch);
|
E int NDECL(tgetch);
|
||||||
E int FDECL(ntposkey,(int *, int *, int *));
|
E int FDECL(ntposkey,(int *, int *, int *));
|
||||||
|
|||||||
@@ -65,6 +65,12 @@
|
|||||||
* objects being thrown when the hangup occurs.
|
* 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 */
|
/* The following is needed for prototypes of certain functions */
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#include <process.h> /* Provides prototypes of exit(), spawn() */
|
#include <process.h> /* Provides prototypes of exit(), spawn() */
|
||||||
|
|||||||
@@ -659,6 +659,10 @@ init_dungeons() /* initialize the "dungeon" structs */
|
|||||||
Strcat(tbuf, DLBFILE);
|
Strcat(tbuf, DLBFILE);
|
||||||
# endif
|
# endif
|
||||||
Strcat(tbuf, "\" file!");
|
Strcat(tbuf, "\" file!");
|
||||||
|
#endif
|
||||||
|
#ifdef WIN32
|
||||||
|
interject_assistance(1, INTERJECT_PANIC, (genericptr_t)tbuf,
|
||||||
|
(genericptr_t)fqn_prefix[DATAPREFIX]);
|
||||||
#endif
|
#endif
|
||||||
panic(tbuf);
|
panic(tbuf);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -298,6 +298,9 @@ panic VA_DECL(const char *, str)
|
|||||||
raw_print(buf);
|
raw_print(buf);
|
||||||
paniclog("panic", buf);
|
paniclog("panic", buf);
|
||||||
}
|
}
|
||||||
|
#ifdef WIN32
|
||||||
|
interject(INTERJECT_PANIC);
|
||||||
|
#endif
|
||||||
#if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE) || defined(WIN32))
|
#if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE) || defined(WIN32))
|
||||||
if (wizard)
|
if (wizard)
|
||||||
NH_abort(); /* generate core dump */
|
NH_abort(); /* generate core dump */
|
||||||
|
|||||||
+3
-3
@@ -379,6 +379,9 @@ char *argv[];
|
|||||||
dlb_init();
|
dlb_init();
|
||||||
|
|
||||||
display_gamewindows();
|
display_gamewindows();
|
||||||
|
#ifdef WIN32
|
||||||
|
getreturn_enabled = TRUE;
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((fd = restore_saved_game()) >= 0) {
|
if ((fd = restore_saved_game()) >= 0) {
|
||||||
#ifdef WIZARD
|
#ifdef WIZARD
|
||||||
@@ -436,9 +439,6 @@ not_recovered:
|
|||||||
#endif
|
#endif
|
||||||
#ifdef OS2
|
#ifdef OS2
|
||||||
gettty(); /* somehow ctrl-P gets turned back on during startup ... */
|
gettty(); /* somehow ctrl-P gets turned back on during startup ... */
|
||||||
#endif
|
|
||||||
#ifdef WIN32
|
|
||||||
getreturn_enabled = TRUE;
|
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+37
-78
@@ -112,6 +112,7 @@ int ttycolors[CLR_MAX];
|
|||||||
# ifdef TEXTCOLOR
|
# ifdef TEXTCOLOR
|
||||||
static void NDECL(init_ttycolor);
|
static void NDECL(init_ttycolor);
|
||||||
# endif
|
# endif
|
||||||
|
static void NDECL(really_move_cursor);
|
||||||
|
|
||||||
#define MAX_OVERRIDES 256
|
#define MAX_OVERRIDES 256
|
||||||
unsigned char key_overrides[MAX_OVERRIDES];
|
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 foreground = (FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
|
||||||
static WORD attr = (FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
|
static WORD attr = (FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
|
||||||
static DWORD ccount, acount;
|
static DWORD ccount, acount;
|
||||||
static COORD cursor;
|
static COORD cursor = {0,0};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called after returning from ! or ^Z
|
* Called after returning from ! or ^Z
|
||||||
@@ -151,7 +152,7 @@ void
|
|||||||
settty(s)
|
settty(s)
|
||||||
const char *s;
|
const char *s;
|
||||||
{
|
{
|
||||||
nocmov(ttyDisplay->curx, ttyDisplay->cury);
|
cmov(ttyDisplay->curx, ttyDisplay->cury);
|
||||||
end_screen();
|
end_screen();
|
||||||
if(s) raw_print(s);
|
if(s) raw_print(s);
|
||||||
}
|
}
|
||||||
@@ -292,6 +293,8 @@ nttty_open()
|
|||||||
cmode = 0; /* just to have a statement to break on for debugger */
|
cmode = 0; /* just to have a statement to break on for debugger */
|
||||||
}
|
}
|
||||||
get_scr_size();
|
get_scr_size();
|
||||||
|
cursor.X = cursor.Y = 0;
|
||||||
|
really_move_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
int process_keystroke(ir, valid, numberpad, portdebug)
|
int process_keystroke(ir, valid, numberpad, portdebug)
|
||||||
@@ -319,8 +322,8 @@ get_scr_size()
|
|||||||
{
|
{
|
||||||
GetConsoleScreenBufferInfo(hConOut, &csbi);
|
GetConsoleScreenBufferInfo(hConOut, &csbi);
|
||||||
|
|
||||||
LI = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
|
LI = csbi.srWindow.Bottom - (csbi.srWindow.Top + 1);
|
||||||
CO = csbi.srWindow.Right - csbi.srWindow.Left + 1;
|
CO = csbi.srWindow.Right - (csbi.srWindow.Left + 1);
|
||||||
|
|
||||||
if ( (LI < 25) || (CO < 80) ) {
|
if ( (LI < 25) || (CO < 80) ) {
|
||||||
COORD newcoord;
|
COORD newcoord;
|
||||||
@@ -341,7 +344,7 @@ tgetch()
|
|||||||
int mod;
|
int mod;
|
||||||
coord cc;
|
coord cc;
|
||||||
DWORD count;
|
DWORD count;
|
||||||
if (iflags.window_inited) nocmov(ttyDisplay->curx, ttyDisplay->cury);
|
really_move_cursor();
|
||||||
return (program_state.done_hup) ?
|
return (program_state.done_hup) ?
|
||||||
'\033' :
|
'\033' :
|
||||||
pCheckInput(hConIn, &ir, &count, iflags.num_pad, 0, &mod, &cc);
|
pCheckInput(hConIn, &ir, &count, iflags.num_pad, 0, &mod, &cc);
|
||||||
@@ -354,7 +357,7 @@ int *x, *y, *mod;
|
|||||||
int ch;
|
int ch;
|
||||||
coord cc;
|
coord cc;
|
||||||
DWORD count;
|
DWORD count;
|
||||||
nocmov(ttyDisplay->curx, ttyDisplay->cury);
|
really_move_cursor();
|
||||||
ch = (program_state.done_hup) ?
|
ch = (program_state.done_hup) ?
|
||||||
'\033' :
|
'\033' :
|
||||||
pCheckInput(hConIn, &ir, &count, iflags.num_pad, 1, mod, &cc);
|
pCheckInput(hConIn, &ir, &count, iflags.num_pad, 1, mod, &cc);
|
||||||
@@ -365,15 +368,20 @@ int *x, *y, *mod;
|
|||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
really_move_cursor()
|
||||||
|
{
|
||||||
|
SetConsoleCursorPosition(hConOut, cursor);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cmov(x, y)
|
cmov(x, y)
|
||||||
register int x, y;
|
register int x, y;
|
||||||
{
|
{
|
||||||
ttyDisplay->curx = x;
|
|
||||||
ttyDisplay->cury = y;
|
|
||||||
cursor.X = x;
|
cursor.X = x;
|
||||||
cursor.Y = y;
|
cursor.Y = y;
|
||||||
SetConsoleCursorPosition(hConOut, cursor);
|
ttyDisplay->curx = x;
|
||||||
|
ttyDisplay->cury = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -382,34 +390,37 @@ int x,y;
|
|||||||
{
|
{
|
||||||
cursor.Y = y;
|
cursor.Y = y;
|
||||||
cursor.X = x;
|
cursor.X = x;
|
||||||
SetConsoleCursorPosition(hConOut, cursor);
|
ttyDisplay->curx = x;
|
||||||
|
ttyDisplay->cury = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xputc(ch)
|
xputc(ch)
|
||||||
char ch;
|
char ch;
|
||||||
{
|
{
|
||||||
cursor.X = ttyDisplay->curx;
|
|
||||||
cursor.Y = ttyDisplay->cury;
|
|
||||||
switch(ch) {
|
switch(ch) {
|
||||||
case '\n':
|
case '\n':
|
||||||
|
cursor.Y++;
|
||||||
|
/* fall through */
|
||||||
case '\r':
|
case '\r':
|
||||||
cmov(cursor.X, cursor.Y);
|
cursor.X = 0;
|
||||||
return;
|
cmov(cursor.X, cursor.Y);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
WriteConsoleOutputAttribute(hConOut,&attr,1,cursor,&acount);
|
WriteConsoleOutputAttribute(hConOut,&attr,1,cursor,&acount);
|
||||||
WriteConsoleOutputCharacter(hConOut,&ch,1,cursor,&ccount);
|
WriteConsoleOutputCharacter(hConOut,&ch,1,cursor,&ccount);
|
||||||
|
cursor.X++;
|
||||||
|
cmov(cursor.X, cursor.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xputs(s)
|
xputs(s)
|
||||||
const char *s;
|
const char *s;
|
||||||
{
|
{
|
||||||
int slen = strlen(s);
|
int k, slen = strlen(s);
|
||||||
cursor.X = ttyDisplay->curx;
|
if (s)
|
||||||
cursor.Y = ttyDisplay->cury;
|
for (k=0; k < slen && s[k]; ++k)
|
||||||
FillConsoleOutputAttribute(hConOut,attr,slen,cursor,&acount);
|
xputc(s[k]);
|
||||||
WriteConsoleOutputCharacter(hConOut,s,slen,cursor,&ccount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -422,16 +433,9 @@ g_putch(in_ch)
|
|||||||
int in_ch;
|
int in_ch;
|
||||||
{
|
{
|
||||||
char ch = (char)in_ch;
|
char ch = (char)in_ch;
|
||||||
|
|
||||||
cursor.X = ttyDisplay->curx;
|
cursor.X = ttyDisplay->curx;
|
||||||
cursor.Y = ttyDisplay->cury;
|
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);
|
WriteConsoleOutputAttribute(hConOut,&attr,1,cursor,&acount);
|
||||||
WriteConsoleOutputCharacter(hConOut,&ch,1,cursor,&ccount);
|
WriteConsoleOutputCharacter(hConOut,&ch,1,cursor,&ccount);
|
||||||
}
|
}
|
||||||
@@ -440,8 +444,6 @@ void
|
|||||||
cl_end()
|
cl_end()
|
||||||
{
|
{
|
||||||
int cx;
|
int cx;
|
||||||
cursor.X = ttyDisplay->curx;
|
|
||||||
cursor.Y = ttyDisplay->cury;
|
|
||||||
cx = CO - cursor.X;
|
cx = CO - cursor.X;
|
||||||
FillConsoleOutputAttribute(hConOut, DEFTEXTCOLOR, cx, cursor, &acount);
|
FillConsoleOutputAttribute(hConOut, DEFTEXTCOLOR, cx, cursor, &acount);
|
||||||
FillConsoleOutputCharacter(hConOut,' ', cx, cursor,&ccount);
|
FillConsoleOutputCharacter(hConOut,' ', cx, cursor,&ccount);
|
||||||
@@ -482,11 +484,9 @@ home()
|
|||||||
void
|
void
|
||||||
backsp()
|
backsp()
|
||||||
{
|
{
|
||||||
GetConsoleScreenBufferInfo(hConOut,&csbi);
|
cursor.X--;
|
||||||
if (csbi.dwCursorPosition.X > 0)
|
xputc(' ');
|
||||||
ntcoord.X = csbi.dwCursorPosition.X-1;
|
cursor.X--;
|
||||||
ntcoord.Y = csbi.dwCursorPosition.Y;
|
|
||||||
SetConsoleCursorPosition(hConOut,ntcoord);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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 */
|
/* this is used when window system isn't initialized yet */
|
||||||
void
|
void
|
||||||
msmsg VA_DECL(const char *, fmt)
|
msmsg VA_DECL(const char *, fmt)
|
||||||
char buf[BUFSZ];
|
char buf[ROWNO * COLNO]; /* worst case scenario */
|
||||||
int slen, k, ac, cc;
|
|
||||||
|
|
||||||
VA_START(fmt);
|
VA_START(fmt);
|
||||||
VA_INIT(fmt, const char *);
|
VA_INIT(fmt, const char *);
|
||||||
Vsprintf(buf, fmt, VA_ARGS);
|
Vsprintf(buf, fmt, VA_ARGS);
|
||||||
VA_END();
|
VA_END();
|
||||||
|
|
||||||
slen = strlen(buf);
|
xputs(buf);
|
||||||
SetConsoleCursorPosition(hConOut, msmsgcursor);
|
really_move_cursor();
|
||||||
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);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -259,6 +259,62 @@ void win32_abort()
|
|||||||
#endif
|
#endif
|
||||||
abort();
|
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 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
/*winnt.c*/
|
/*winnt.c*/
|
||||||
|
|||||||
@@ -793,9 +793,6 @@ tty_exit_nhwindows(str)
|
|||||||
}
|
}
|
||||||
#ifndef NO_TERMS /*(until this gets added to the window interface)*/
|
#ifndef NO_TERMS /*(until this gets added to the window interface)*/
|
||||||
tty_shutdown(); /* cleanup termcap/terminfo/whatever */
|
tty_shutdown(); /* cleanup termcap/terminfo/whatever */
|
||||||
#endif
|
|
||||||
#ifdef WIN32CON
|
|
||||||
nttty_close();
|
|
||||||
#endif
|
#endif
|
||||||
iflags.window_inited = 0;
|
iflags.window_inited = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user