From 028408e1238a39aaa27dd32052f89a928192dba4 Mon Sep 17 00:00:00 2001 From: jwalz Date: Sat, 5 Jan 2002 21:05:58 +0000 Subject: [PATCH] *** empty log message *** --- sys/share/pcmain.c | 649 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 649 insertions(+) create mode 100644 sys/share/pcmain.c diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c new file mode 100644 index 000000000..0996d2be8 --- /dev/null +++ b/sys/share/pcmain.c @@ -0,0 +1,649 @@ +/* SCCS Id: @(#)pcmain.c 3.3 97/01/22 */ +/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ +/* NetHack may be freely redistributed. See license for details. */ + +/* main.c - MSDOS, OS/2, ST, Amiga, and NT NetHack */ + +#include "hack.h" +#include "dlb.h" + +#ifndef NO_SIGNAL +#include +#endif + +#include + +#if !defined(AMIGA) && !defined(GNUDOS) +#include +#else +# ifdef GNUDOS +#include +# endif +#endif + +#ifdef WIN32 +#include "win32api.h" /* for GetModuleFileName */ +#endif + +#ifdef __DJGPP__ +#include /* for getcwd() prototype */ +#endif + +#ifdef OVL0 +#define SHARED_DCL +#else +#define SHARED_DCL extern +#endif + + +SHARED_DCL char orgdir[PATHLEN]; /* also used in pcsys.c, amidos.c */ + +#ifdef TOS +boolean run_from_desktop = TRUE; /* should we pause before exiting?? */ +# ifdef __GNUC__ +long _stksize = 16*1024; +# endif +#endif + +#ifdef AMIGA +extern int bigscreen; +void NDECL( preserve_icon ); +#endif + +STATIC_DCL void FDECL(process_options,(int argc,char **argv)); +STATIC_DCL void NDECL(nhusage); + +#if defined(MICRO) || defined(WIN32) || defined(OS2) +extern void FDECL(nethack_exit,(int)); +#else +#define nethack_exit exit +#endif + +#ifdef EXEPATH +STATIC_DCL char *FDECL(exepath,(char *)); +#endif + +#ifdef OVL0 +int FDECL(main, (int,char **)); +#endif + +extern void FDECL(pcmain, (int,char **)); + + +#if defined(__BORLANDC__) && !defined(_WIN32) +void NDECL( startup ); +# ifdef OVLB +unsigned _stklen = STKSIZ; +# else +extern unsigned _stklen; +# endif +#endif + +#ifdef OVL0 +int +main(argc,argv) +int argc; +char *argv[]; +{ + pcmain(argc,argv); +#ifdef LAN_FEATURES + init_lan_features(); +#endif + moveloop(); + nethack_exit(EXIT_SUCCESS); + /*NOTREACHED*/ + return 0; +} +#endif /*OVL0*/ +#ifdef OVL1 + +void +pcmain(argc,argv) +int argc; +char *argv[]; +{ + + register int fd; + register char *dir; + +#if defined(__BORLANDC__) && !defined(_WIN32) + startup(); +#endif + +#ifdef TOS + long clock_time; + if (*argv[0]) { /* only a CLI can give us argv[0] */ + hname = argv[0]; + run_from_desktop = FALSE; + } else +#endif + hname = "NetHack"; /* used for syntax messages */ + + choose_windows(DEFAULT_WINDOW_SYS); + +#if !defined(AMIGA) && !defined(GNUDOS) + /* Save current directory and make sure it gets restored when + * the game is exited. + */ + if (getcwd(orgdir, sizeof orgdir) == (char *)0) + error("NetHack: current directory path too long"); +# ifndef NO_SIGNAL + signal(SIGINT, (SIG_RET_TYPE) nethack_exit); /* restore original directory */ +# endif +#endif /* !AMIGA && !GNUDOS */ + + dir = nh_getenv("NETHACKDIR"); + if (dir == (char *)0) + dir = nh_getenv("HACKDIR"); +#ifdef EXEPATH + if (dir == (char *)0) + dir = exepath(argv[0]); +#endif + if (dir != (char *)0) { + (void) strncpy(hackdir, dir, PATHLEN - 1); + hackdir[PATHLEN-1] = '\0'; +#ifdef NOCWD_ASSUMPTIONS + { + int prefcnt; + + fqn_prefix[0] = (char *)alloc(strlen(hackdir)+2); + Strcpy(fqn_prefix[0], hackdir); + append_slash(fqn_prefix[0]); + for (prefcnt = 1; prefcnt < PREFIX_COUNT; prefcnt++) + fqn_prefix[prefcnt] = fqn_prefix[0]; + } +#endif +#ifdef CHDIR + chdirx (dir, 1); +#endif + } +#ifdef AMIGA +# ifdef CHDIR + /* + * If we're dealing with workbench, change the directory. Otherwise + * we could get "Insert disk in drive 0" messages. (Must be done + * before initoptions()).... + */ + if(argc == 0) + chdirx(HACKDIR, 1); +# endif + ami_wininit_data(); +#endif + initoptions(); + +#if defined(TOS) && defined(TEXTCOLOR) + if (iflags.BIOS && iflags.use_color) + set_colors(); +#endif + if (!hackdir[0]) +#if !defined(LATTICE) && !defined(AMIGA) + Strcpy(hackdir, orgdir); +#else + Strcpy(hackdir, HACKDIR); +#endif + if(argc > 1) { + if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') { + /* avoid matching "-dec" for DECgraphics; since the man page + * says -d directory, hope nobody's using -desomething_else + */ + argc--; + argv++; + dir = argv[0]+2; + if(*dir == '=' || *dir == ':') dir++; + if(!*dir && argc > 1) { + argc--; + argv++; + dir = argv[0]; + } + if(!*dir) + error("Flag -d must be followed by a directory name."); + Strcpy(hackdir, dir); + } + if (argc > 1) { + + /* + * Now we know the directory containing 'record' and + * may do a prscore(). + */ + if (!strncmp(argv[1], "-s", 2)) { +#ifdef CHDIR + chdirx(hackdir,0); +#endif + prscore(argc, argv); + nethack_exit(EXIT_SUCCESS); + } + /* Don't initialize the window system just to print usage */ + if (!strncmp(argv[1], "-?", 2) || !strncmp(argv[1], "/?", 2)) { + nhusage(); + nethack_exit(EXIT_SUCCESS); + } + } + } + + /* + * It seems you really want to play. + */ +#ifdef TOS + if (comp_times((long)time(&clock_time))) + error("Your clock is incorrectly set!"); +#endif + u.uhp = 1; /* prevent RIP on early quits */ + u.ux = 0; /* prevent flush_screen() */ + + /* chdir shouldn't be called before this point to keep the + * code parallel to other ports which call gethdate just + * before here. + */ +#ifdef CHDIR + chdirx(hackdir,1); +#endif + +#ifdef MSDOS + process_options(argc, argv); + init_nhwindows(&argc,argv); +#else + init_nhwindows(&argc,argv); + process_options(argc, argv); +#endif + +#ifdef MFLOPPY + set_lock_and_bones(); +# ifndef AMIGA + copybones(FROMPERM); +# endif +#endif + + if (!*plname) + askname(); + plnamesuffix(); /* strip suffix from name; calls askname() */ + /* again if suffix was whole name */ + /* accepts any suffix */ +#ifdef WIZARD + if (wizard) { +# ifdef KR1ED + if(!strcmp(plname, WIZARD_NAME)) +# else + if(!strcmp(plname, WIZARD)) +# endif + Strcpy(plname, "wizard"); + else { + wizard = FALSE; + discover = TRUE; + } + } +#endif /* WIZARD */ +#if defined(PC_LOCKING) + /* 3.3.0 added this to support detection of multiple games + * under the same plname on the same machine in a windowed + * or multitasking environment. + * + * That allows user confirmation prior to overwriting the + * level files of a game in progress. + * + * Also prevents an aborted game's level files from being + * overwritten without confirmation when a user starts up + * another game with the same player name. + */ +# if defined(WIN32) + /* Obtain the name of the logged on user and incorporate + * it into the name. */ + Sprintf(lock, "%s-%s",get_username(0),plname); +# else + Strcpy(lock,plname); + regularize(lock); +# endif + getlock(); +#else /* PC_LOCKING */ +# ifdef AMIGA /* We'll put the bones & levels in the user specified directory -jhsa */ + Strcat(lock,plname); + Strcat(lock,".99"); +# else +# ifndef MFLOPPY + /* I'm not sure what, if anything, is left here, but MFLOPPY has + * conflicts with set_lock_and_bones() in files.c. + */ + Strcpy(lock,plname); + Strcat(lock,".99"); + regularize(lock); /* is this necessary? */ + /* not compatible with full path a la AMIGA */ +# endif +# endif +#endif /* PC_LOCKING */ + + /* Set up level 0 file to keep the game state. + */ + fd = create_levelfile(0); + if (fd < 0) { + raw_print("Cannot create lock file"); + } else { + hackpid = 1; + write(fd, (genericptr_t) &hackpid, sizeof(hackpid)); + close(fd); + } +#ifdef MFLOPPY + level_info[0].where = ACTIVE; +#endif + + /* + * Initialisation of the boundaries of the mazes + * Both boundaries have to be even. + */ + + x_maze_max = COLNO-1; + if (x_maze_max % 2) + x_maze_max--; + y_maze_max = ROWNO-1; + if (y_maze_max % 2) + y_maze_max--; + + /* + * Initialize the vision system. This must be before mklev() on a + * new game or before a level restore on a saved game. + */ + vision_init(); + + dlb_init(); + + display_gamewindows(); + + if ((fd = restore_saved_game()) >= 0) { +#ifdef WIZARD + /* Since wizard is actually flags.debug, restoring might + * overwrite it. + */ + boolean remember_wiz_mode = wizard; +#endif +#ifndef NO_SIGNAL + (void) signal(SIGINT, (SIG_RET_TYPE) done1); +#endif +#ifdef NEWS + if(iflags.news){ + display_file(NEWS, FALSE); + iflags.news = FALSE; + } +#endif + pline("Restoring save file..."); + mark_synch(); /* flush output */ + + if(!dorecover(fd)) + goto not_recovered; +#ifdef WIZARD + if(!wizard && remember_wiz_mode) wizard = TRUE; +#endif + check_special_room(FALSE); + if (discover) + You("are in non-scoring discovery mode."); + + if (discover || wizard) { + if(yn("Do you want to keep the save file?") == 'n'){ + (void) delete_savefile(); + } + } + + flags.move = 0; + } else { +not_recovered: + player_selection(); + newgame(); + if (discover) + You("are in non-scoring discovery mode."); + + flags.move = 0; + set_wear(); + (void) pickup(1); + read_engr_at(u.ux,u.uy); + } + +#ifndef NO_SIGNAL + (void) signal(SIGINT, SIG_IGN); +#endif +#ifdef OS2 + gettty(); /* somehow ctrl-P gets turned back on during startup ... */ +#endif + + return; +} + +STATIC_OVL void +process_options(argc, argv) +int argc; +char *argv[]; +{ + int i; + + + /* + * Process options. + */ + while(argc > 1 && argv[1][0] == '-'){ + argv++; + argc--; + switch(argv[0][1]){ + case 'a': + if (argv[0][2]) { + if ((i = str2align(&argv[0][2])) >= 0) + flags.initalign = i; + } else if (argc > 1) { + argc--; + argv++; + if ((i = str2align(argv[0])) >= 0) + flags.initalign = i; + } + break; + case 'D': +#ifdef WIZARD + /* If they don't have a valid wizard name, it'll be + * changed to discover later. Cannot check for + * validity of the name right now--it might have a + * character class suffix, for instance. + */ + wizard = TRUE; + break; +#endif + case 'X': + discover = TRUE; + break; +#ifdef NEWS + case 'n': + iflags.news = FALSE; + break; +#endif + case 'u': + if(argv[0][2]) + (void) strncpy(plname, argv[0]+2, sizeof(plname)-1); + else if(argc > 1) { + argc--; + argv++; + (void) strncpy(plname, argv[0], sizeof(plname)-1); + } else + raw_print("Player name expected after -u"); + break; +#ifndef AMIGA + case 'I': + case 'i': + if (!strncmpi(argv[0]+1, "IBM", 3)) + switch_graphics(IBM_GRAPHICS); + break; + /* case 'D': */ + case 'd': + if (!strncmpi(argv[0]+1, "DEC", 3)) + switch_graphics(DEC_GRAPHICS); + break; +#endif + case 'g': + if (argv[0][2]) { + if ((i = str2gend(&argv[0][2])) >= 0) + flags.initgend = i; + } else if (argc > 1) { + argc--; + argv++; + if ((i = str2gend(argv[0])) >= 0) + flags.initgend = i; + } + break; + case 'p': /* profession (role) */ + if (argv[0][2]) { + if ((i = str2role(&argv[0][2])) >= 0) + flags.initrole = i; + } else if (argc > 1) { + argc--; + argv++; + if ((i = str2role(argv[0])) >= 0) + flags.initrole = i; + } + break; + case 'r': /* race */ + if (argv[0][2]) { + if ((i = str2race(&argv[0][2])) >= 0) + flags.initrace = i; + } else if (argc > 1) { + argc--; + argv++; + if ((i = str2race(argv[0])) >= 0) + flags.initrace = i; + } + break; +#ifdef MFLOPPY +# ifndef AMIGA + /* Player doesn't want to use a RAM disk + */ + case 'R': + ramdisk = FALSE; + break; +# endif +#endif +#ifdef AMIGA + /* interlaced and non-interlaced screens */ + case 'L': + bigscreen = 1; + break; + case 'l': + bigscreen = -1; + break; +#endif + case '@': + flags.randomall = 1; + break; + default: + if ((i = str2role(&argv[0][1])) >= 0) { + flags.initrole = i; + break; + } else raw_printf("\nUnknown switch: %s", argv[0]); + /* FALL THROUGH */ + case '?': + nhusage(); + nethack_exit(EXIT_SUCCESS); + } + } +} + +STATIC_OVL void +nhusage() +{ + char buf1[BUFSZ]; + + /* -role still works for those cases which aren't already taken, but + * is deprecated and will not be listed here. + */ + (void) Sprintf(buf1, +"\nUsage: %s [-d dir] -s [-r race] [-p profession] [maxrank] [name]...\n or", + hname); + if (!iflags.window_inited) + raw_printf(buf1); + else + (void) printf(buf1); + (void) Sprintf(buf1, + "\n %s [-d dir] [-u name] [-r race] [-p profession] [-[DX]]", + hname); +#ifdef NEWS + Strcat(buf1," [-n]"); +#endif +#ifndef AMIGA + Strcat(buf1," [-I] [-i] [-d]"); +#endif +#ifdef MFLOPPY +# ifndef AMIGA + Strcat(buf1," [-R]"); +# endif +#endif +#ifdef AMIGA + Strcat(buf1," [-[lL]]"); +#endif + if (!iflags.window_inited) + raw_printf("%s\n",buf1); + else + (void) printf("%s\n",buf1); +} + +#ifdef CHDIR +void +chdirx(dir, wr) +char *dir; +boolean wr; +{ +# ifdef AMIGA + static char thisdir[] = ""; +# else + static char thisdir[] = "."; +# endif + if(dir && chdir(dir) < 0) { + error("Cannot chdir to %s.", dir); + } + +# ifndef AMIGA + /* Change the default drive as well. + */ + chdrive(dir); +# endif + + /* warn the player if we can't write the record file */ + /* perhaps we should also test whether . is writable */ + /* unfortunately the access system-call is worthless */ + if (wr) check_recordfile(dir ? dir : thisdir); +} +#endif /* CHDIR */ +#endif /*OVL1*/ +#ifdef OVLB + +#ifdef PORT_HELP +# if defined(MSDOS) || defined(WIN32) +void +port_help() +{ + /* display port specific help file */ + display_file( PORT_HELP, 1 ); +} +# endif /* MSDOS || WIN32 */ +#endif /* PORT_HELP */ + +#ifdef EXEPATH +# ifdef __DJGPP__ +#define PATH_SEPARATOR '/' +# else +#define PATH_SEPARATOR '\\' +# endif + +#define EXEPATHBUFSZ 256 +char exepathbuf[EXEPATHBUFSZ]; + +char *exepath(str) +char *str; +{ + char *tmp, *tmp2; + int bsize; + + if (!str) return (char *)0; + bsize = EXEPATHBUFSZ; + tmp = exepathbuf; +# ifndef WIN32 + Strcpy (tmp, str); +# else + *(tmp + GetModuleFileName((HANDLE)0, tmp, bsize)) = '\0'; +# endif + tmp2 = strrchr(tmp, PATH_SEPARATOR); + if (tmp2) *tmp2 = '\0'; + return tmp; +} +#endif /* EXEPATH */ +#endif /*OVLB*/ +/*pcmain.c*/ -- 2.50.1