home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume16 / nethck31 / patch2dd < prev    next >
Encoding:
Internet Message Format  |  1993-06-15  |  60.1 KB

  1. Path: uunet!news.tek.com!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v17i105:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Patch2dd/33
  5. Date: 11 Jun 1993 00:19:25 GMT
  6. Organization: Tektronix, Inc, Redmond, OR, USA
  7. Lines: 1990
  8. Approved: billr@saab.CNA.TEK.COM
  9. Message-ID: <1v8j2d$je0@ying.cna.tek.com>
  10. NNTP-Posting-Host: saab.cna.tek.com
  11. Xref: uunet comp.sources.games:1787
  12.  
  13. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  14. Posting-number: Volume 17, Issue 105
  15. Archive-name: nethack31/Patch2dd
  16. Patch-To: nethack31: Volume 16, Issue 1-116
  17. Environment: Amiga, Atari, Mac, MS-DOS, Windows-NT, OS2, Unix, VMS, X11
  18.  
  19.  
  20.  
  21. #! /bin/sh
  22. # This is a shell archive.  Remove anything before this line, then unpack
  23. # it by saving it into a file and typing "sh file".  To overwrite existing
  24. # files, type "sh file -c".  You can also feed this as standard input via
  25. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  26. # will see the following message at the end:
  27. #        "End of archive 30 (of 33)."
  28. # Contents:  sys/mac/mrecover.c sys/os2/Install.os2
  29. #   sys/winnt/Install.nt
  30. # Wrapped by billr@saab on Thu Jun 10 16:55:08 1993
  31. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  32. if test -f 'sys/mac/mrecover.c' -a "${1}" != "-c" ; then 
  33.   echo shar: Renaming existing file \"'sys/mac/mrecover.c'\" to \"'sys/mac/mrecover.c.orig'\"
  34.   mv -f 'sys/mac/mrecover.c' 'sys/mac/mrecover.c.orig'
  35. fi
  36. echo shar: Extracting \"'sys/mac/mrecover.c'\" \(30445 characters\)
  37. sed "s/^X//" >'sys/mac/mrecover.c' <<'END_OF_FILE'
  38. X/*    SCCS Id: @(#)mrecover.c    3.1               93/04/15       */
  39. X/*      Copyright (c) David Hairston, 1993.                       */
  40. X/* NetHack may be freely redistributed.  See license for details. */
  41. X
  42. X/* Macintosh Recovery Application */
  43. X
  44. X/* based on code in util/recover.c.  the significant differences are:
  45. X * - define MAC is implicit so config.h is not included (95% laziness).
  46. X * - GUI vs. CLI.  the vast majority of code here supports the GUI.
  47. X * - Mac toolbox equivalents are used in place of ANSI functions.
  48. X * - void restore_savefile(void) is event driven.
  49. X * - integral type substitutions here and there.
  50. X */
  51. X
  52. X/*
  53. X * Think C 5.0.4 project specs:
  54. X * signature: 'nhRc'
  55. X * SIZE (-1) info: flags: 0x5880, size: 65536L/65536L (64k/64k)
  56. X * libraries: MacTraps [yes], MacTraps2 (HFileStuff) [yes], ANSI [no]
  57. X * compatibility: system 6 and system 7
  58. X * misc: sizeof(int): 4, "\p": unsigned char, enum size varies,
  59. X *   prototypes required, type checking enforced, no optimizers,
  60. X *   FAR CODE [no], FAR DATA [no], SEPARATE STRS [no], single segment,
  61. X *   short macsbug symbols
  62. X */
  63. X/*
  64. X * To do (maybe, just maybe):
  65. X * - Merge with the code in util/recover.c.
  66. X * - Document launch (e.g. GUI equivalent of 'recover basename').
  67. X * - Drag and drop.
  68. X * - Internal memory tweaks (stack and heap usage).
  69. X * - Use status file to allow resuming aborted recoveries.
  70. X * - Bundle 'LEVL' files with recover (easier document launch).
  71. X * - Prohibit recovering games "in progress".
  72. X * - Share AppleEvents with NetHack to auto-recover crashed games.
  73. X */
  74. X
  75. X#if 1
  76. X/************************************************************************\
  77. X * (1) precompile header => mrecover.h, (0) compile code
  78. X\************************************************************************/
  79. X
  80. X/**** Toolbox defines ****/
  81. X
  82. X/* MPW C headers (99.44% pure) */
  83. X#include <Types.h>
  84. X#include <Errors.h>
  85. X#include <Memory.h>
  86. X#include <OSUtils.h>
  87. X#include <Resources.h>
  88. X#include <Files.h>
  89. X#include <SysEqu.h>
  90. X#include <SegLoad.h>
  91. X
  92. X#include <Quickdraw.h>
  93. X#include <Fonts.h>
  94. X#include <Windows.h>
  95. X#include <Menus.h>
  96. X#include <Dialogs.h>
  97. X
  98. X#include <Desk.h>
  99. X#include <DiskInit.h>
  100. X#include <Events.h>
  101. X#include <Notification.h>
  102. X#include <Packages.h>
  103. X#include <Script.h>
  104. X#include <StandardFile.h>
  105. X#include <ToolUtils.h>
  106. X
  107. X#if 1    /* glue for System 7 Icon Family call (needed by Think C 5.0.4) */
  108. Xpascal OSErr GetIconSuite(Handle *theIconSuite, short theResID, long selector)
  109. X    = {0x303C, 0x0501, 0xABC9};
  110. X#endif
  111. X
  112. X
  113. X/**** Application defines ****/
  114. X
  115. X/* Memory */
  116. Xtypedef struct memBytes    /* format of 'memB' resource, preloaded/locked */
  117. X{
  118. X    short    memReserved;
  119. X    short    memCleanup;    /* 4   - memory monitor activity limit */
  120. X    long    memPreempt;    /* 32k - start iff FreeMem() > */
  121. X    long    memWarning;    /* 12k - warn if MaxMem() < */
  122. X    long    memAbort;    /* 4k  - abort if MaxMem() < */
  123. X    long    memIOBuf;    /* 16k - read/write buffer size */
  124. X} memBytes, *memBytesPtr, **memBytesHandle;
  125. X
  126. X#define membID            128                /* 'memB' resource ID */
  127. X
  128. X
  129. X/* Cursor */
  130. X#define CURS_FRAME        4L                /* 1/15 second - spin cursor */
  131. X#define CURS_LATENT        60L                /* pause before spin cursor */
  132. X#define curs_Init        (-1)            /* token for set arrow */
  133. X#define curs_Total        8                /* maybe 'acur' would be better */
  134. X#define cursorOffset    128                /* GetCursor(cursorOffset + i) */
  135. X
  136. X
  137. X/* Menu */
  138. Xenum
  139. X{
  140. X    mbar_Init = -1,
  141. X    mbarAppl,                            /* normal mode */
  142. X    mbarRecover,                        /* in recovery mode */
  143. X    mbarDA                                /* DA in front mode */
  144. X};
  145. Xenum
  146. X{
  147. X    menuApple,
  148. X    menuFile,
  149. X    menuEdit,
  150. X    menu_Total,
  151. X
  152. X    muidApple = 128,
  153. X    muidFile,
  154. X    muidEdit
  155. X};
  156. Xenum
  157. X{
  158. X    /* Apple menu */
  159. X    mitmAbout = 1,
  160. X    mitmHelp,
  161. X    ____128_1,
  162. X
  163. X    /* File menu */
  164. X    mitmOpen = 1,
  165. X    ____129_1,
  166. X    mitmClose_DA,
  167. X    ____129_2,
  168. X    mitmQuit
  169. X
  170. X    /* standard minimum required Edit menu */
  171. X};
  172. X
  173. X
  174. X/* Alerts */
  175. Xenum
  176. X{
  177. X    alrtNote,                            /* general messages */
  178. X    alrtHelp,                            /* help message */
  179. X    alrt_Total,
  180. X
  181. X    alertAppleMenu = 127,                /* menuItem to alert ID offset */
  182. X    alidNote,
  183. X    alidHelp
  184. X};
  185. X
  186. X#define aboutBufSize    80                /* i.e. 2 lines of 320 pixels */
  187. X
  188. X
  189. X/* Notification */
  190. X#define nmBufSize        (32 + aboutBufSize + 32)
  191. Xtypedef struct notifRec
  192. X{
  193. X    NMRec                nmr;
  194. X    struct notifRec    *    nmNext;
  195. X    short                nmDispose;
  196. X    unsigned char        nmBuf[nmBufSize];
  197. X} notifRec, *notifPtr;
  198. X
  199. X#define nmPending        nmRefCon            /* &in.Notify */
  200. X#define iconNotifyID    128
  201. X#define ics_1_and_4        0x00000300
  202. X
  203. X/* Dialogs */
  204. Xenum
  205. X{
  206. X    dlogProgress = 256
  207. X};
  208. Xenum
  209. X{
  210. X    uitmThermo = 1
  211. X};
  212. Xenum
  213. X{
  214. X    initItem,
  215. X    invalItem,
  216. X    drawItem
  217. X};
  218. X
  219. X
  220. X/* Miscellaneous */
  221. Xtypedef struct modeFlags
  222. X{
  223. X    short    Front;            /* fg/bg event handling */
  224. X    short    Notify;            /* level of pending NM notifications */
  225. X    short    Dialog;            /* a modeless dialog is open */
  226. X    short    Recover;        /* restoration progress index */
  227. X} modeFlags;
  228. X
  229. X/* convenient define to allow easier (for me) parsing of 'vers' resource */
  230. Xtypedef struct versXRec
  231. X{
  232. X    NumVersion        numVers;
  233. X    short            placeCode;
  234. X    unsigned char    versStr[];    /* (small string)(large string) */
  235. X} versXRec, *versXPtr, **versXHandle;
  236. X
  237. X#else
  238. X/************************************************************************\
  239. X * compile source code
  240. X\************************************************************************/
  241. X
  242. X#include "mrecover.h"
  243. X
  244. X/**** Global variables ****/
  245. XmodeFlags        in = {1};                /* in Front */
  246. XEventRecord        wnEvt;
  247. XSysEnvRec        sysEnv;
  248. Xunsigned char    aboutBuf[aboutBufSize];    /* vers 1 "Get Info" string */
  249. XmemBytesPtr        pBytes;                    /* memory management */
  250. Xunsigned short    memActivity;            /* more memory management */
  251. XMenuHandle        mHnd[menu_Total];
  252. XCursPtr            cPtr[curs_Total];        /* busy cursors */
  253. Xunsigned long    timeCursor;                /* next cursor frame time */
  254. Xshort            oldCursor = curs_Init;    /* see adjustGUI() below */
  255. XnotifPtr        pNMQ;                    /* notification queue pointer */
  256. XnotifRec        nmt;                    /* notification template */
  257. XDialogTHndl        thermoTHnd;
  258. XDialogRecord    dlgThermo;                /* progress thermometer */
  259. X#define DLGTHM    ((DialogPtr) &dlgThermo)
  260. X#define WNDTHM    ((WindowPtr) &dlgThermo)
  261. X#define GRFTHM    ((GrafPtr) &dlgThermo)
  262. X
  263. XPoint            sfGetWhere;                /* top left corner of get file dialog */
  264. XPtr                pIOBuf;                    /* read/write buffer pointer */
  265. Xshort            vRefNum;                /* SFGetFile working directory/volume refnum */
  266. Xlong            dirID;                    /* directory i.d. */
  267. X
  268. X#define CREATOR        'nh31'                /* NetHack signature */
  269. X#define SAVETYPE    'SAVE'                /* save file type */
  270. X#define FILENAME    256                    /* macconf.h */
  271. Xtypedef signed char    schar;                /* config.h */
  272. Xtypedef schar        xchar;                /* global.h */
  273. X#define MAX_RECOVER_COUNT    256
  274. X
  275. X#define APP_NAME_RES_ID        (-16396)    /* macfile.h */
  276. X#define PLAYER_NAME_RES_ID    1001        /* macfile.h */
  277. X
  278. X/* variables from util/recover.c */
  279. X#define SAVESIZE    FILENAME
  280. Xunsigned char    savename[SAVESIZE];        /* originally a C string */
  281. Xunsigned char    lock[256];                /* pascal string */
  282. X
  283. Xlong            hpid;                    /* NetHack (unix-style) process i.d. */
  284. Xshort            saveRefNum;                /* save file descriptor */
  285. Xshort            gameRefNum;                /* level 0 file descriptor */
  286. Xshort            levRefNum;                /* level n file descriptor */
  287. X
  288. X
  289. X/**** Prototypes ****/
  290. Xstatic    void warmup(void);
  291. Xstatic    Handle alignTemplate(ResType, short, short, short, Point *);
  292. Xpascal    void nmCompletion(NMRec *);
  293. Xstatic    void noteErrorMessage(unsigned char *, unsigned char *);
  294. Xstatic    void note(short, short, unsigned char *);
  295. Xstatic    void adjustGUI(void);
  296. Xstatic    void adjustMemory(void);
  297. Xstatic    void optionMemStats(void);
  298. Xstatic    void MenuEvent(long);
  299. Xstatic    void eventLoop(void);
  300. Xstatic    void cooldown(void);
  301. X
  302. Xpascal    void drawThermo(WindowPtr, short);
  303. Xstatic    void itemizeThermo(short);
  304. Xpascal    Boolean basenameFileFilter(ParmBlkPtr);
  305. Xstatic    void beginRecover(void);
  306. Xstatic    void continueRecover(void);
  307. Xstatic    void endRecover(void);
  308. Xstatic    short saveRezStrings(void);
  309. X
  310. X/* analogous prototypes from util/recover.c */
  311. Xstatic    void set_levelfile_name(long);
  312. Xstatic    short open_levelfile(long);
  313. Xstatic    short create_savefile(unsigned char *);
  314. Xstatic    void copy_bytes(short, short);
  315. Xstatic    void restore_savefile(void);
  316. X
  317. X/* auxiliary prototypes */
  318. Xstatic    long read_levelfile(short, Ptr, long);
  319. Xstatic    long write_savefile(short, Ptr, long);
  320. Xstatic    void close_file(short *);
  321. Xstatic    void unlink_file(unsigned char *);
  322. X
  323. X
  324. X/**** Routines ****/
  325. X
  326. Xmain()
  327. X{
  328. X    /* heap adjust */
  329. X    MaxApplZone();
  330. X    MoreMasters();
  331. X    MoreMasters();
  332. X
  333. X    /* manager initialization */
  334. X    InitGraf(&qd.thePort);
  335. X    InitFonts();
  336. X    InitWindows();
  337. X    InitMenus();
  338. X    TEInit();
  339. X    InitDialogs((ResumeProcPtr) 0);
  340. X    InitCursor();
  341. X
  342. X    /* get system environment, notification requires 6.0 or better */
  343. X    (void) SysEnvirons(curSysEnvVers, &sysEnv);
  344. X    if (sysEnv.systemVersion < 0x0600)
  345. X    {
  346. X        ParamText("\pAbort: System 6.0 is required", "\p", "\p", "\p");
  347. X        (void) Alert(alidNote, (ModalFilterProcPtr) 0L);
  348. X        ExitToShell();
  349. X    }
  350. X
  351. X    warmup();
  352. X    eventLoop();
  353. X
  354. X    /* normally these routines are never reached from here */
  355. X    cooldown();
  356. X    ExitToShell();
  357. X}
  358. X
  359. Xstatic void
  360. Xwarmup()
  361. X{
  362. X    short        i;
  363. X
  364. X    /* pre-System 7 MultiFinder hack for smooth launch */
  365. X    for (i = 0; i < 10; i++)
  366. X    {
  367. X        if (WaitNextEvent(osMask, &wnEvt, 2L, (RgnHandle) 0L))
  368. X            if (((wnEvt.message & osEvtMessageMask) >> 24) == suspendResumeMessage)
  369. X                in.Front = (wnEvt.message & resumeFlag);
  370. X    }
  371. X
  372. X    /* clear out the Finder info */
  373. X    {
  374. X        short    message, count;
  375. X
  376. X        CountAppFiles(&message, &count);
  377. X        while(count)
  378. X            ClrAppFiles(count--);
  379. X    }
  380. X
  381. X    /* fill out the notification template */
  382. X    nmt.nmr.qType = nmType;
  383. X    nmt.nmr.nmMark = 1;
  384. X    nmt.nmr.nmSound = (Handle) -1L;        /* system beep */
  385. X    nmt.nmr.nmStr = nmt.nmBuf;
  386. X    nmt.nmr.nmResp = nmCompletion;
  387. X    nmt.nmr.nmPending = (long) &in.Notify;
  388. X
  389. X    /* prepend app name (31 chars or less) to notification buffer */
  390. X    {
  391. X        short    apRefNum;
  392. X        Handle    apParams;
  393. X
  394. X        GetAppParms(* (Str255 *) &nmt.nmBuf, &apRefNum, &apParams);
  395. X    }
  396. X
  397. X    /* add formatting (two line returns) */
  398. X    nmt.nmBuf[++(nmt.nmBuf[0])] = '\r';
  399. X    nmt.nmBuf[++(nmt.nmBuf[0])] = '\r';
  400. X
  401. X    /**** note() is usable now but not aesthetically complete ****/
  402. X
  403. X    /* get notification icon */
  404. X    if (sysEnv.systemVersion < 0x0700)
  405. X    {
  406. X        if (! (nmt.nmr.nmIcon = GetResource('SICN', iconNotifyID)))
  407. X            note(nilHandleErr, 0, "\pNil SICN Handle");
  408. X    }
  409. X    else
  410. X    {
  411. X        if (GetIconSuite(&nmt.nmr.nmIcon, iconNotifyID, ics_1_and_4))
  412. X            note(nilHandleErr, 0, "\pBad Icon Family");
  413. X    }
  414. X
  415. X    /* load and align various dialog/alert templates */
  416. X    (void) alignTemplate('ALRT', alidNote, 0, 4, (Point *) 0L);
  417. X    (void) alignTemplate('ALRT', alidHelp, 0, 4, (Point *) 0L);
  418. X
  419. X    thermoTHnd = (DialogTHndl) alignTemplate('DLOG', dlogProgress, 20, 8, (Point *) 0L);
  420. X
  421. X    (void) alignTemplate('DLOG', getDlgID, 0, 6, (Point *) &sfGetWhere);
  422. X
  423. X    /* get the "busy cursors" (preloaded/locked) */
  424. X    for (i = 0; i < curs_Total; i++)
  425. X    {
  426. X        CursHandle        cHnd;
  427. X
  428. X        if (! (cHnd = GetCursor(i + cursorOffset)))
  429. X            note(nilHandleErr, 0, "\pNil CURS Handle");
  430. X
  431. X        cPtr[i] = *cHnd;
  432. X    }
  433. X
  434. X    /* get the 'vers' 1 long (Get Info) string - About Recover... */
  435. X    {
  436. X        versXHandle        vHnd;
  437. X
  438. X        if (! (vHnd = (versXHandle) GetResource('vers', 1)))
  439. X            note(nilHandleErr, 0, "\pNil vers Handle");
  440. X
  441. X        i = (**vHnd).versStr[0] + 1;        /* offset to Get Info pascal string */
  442. X
  443. X        if ((aboutBuf[0] = (**vHnd).versStr[i]) > (aboutBufSize - 1))
  444. X            aboutBuf[0] = aboutBufSize - 1;
  445. X
  446. X        i++;
  447. X
  448. X        MoveHHi((Handle) vHnd);            /* DEE - Fense ... */
  449. X        HLock((Handle) vHnd);
  450. X        BlockMove(&((**vHnd).versStr[i]), &(aboutBuf[1]), aboutBuf[0]);
  451. X        ReleaseResource((Handle) vHnd);
  452. X    }
  453. X
  454. X    /* form the menubar */
  455. X    for (i = 0; i < menu_Total; i++)
  456. X    {
  457. X        if (! (mHnd[i] = GetMenu(i + muidApple)))
  458. X            note(nilHandleErr, 0, "\pNil MENU Handle");
  459. X
  460. X        /* expand the apple menu */
  461. X        if (i == menuApple)
  462. X            AddResMenu(mHnd[menuApple], 'DRVR');
  463. X
  464. X        InsertMenu(mHnd[i], 0);
  465. X    }
  466. X
  467. X    /* pre-emptive memory check */
  468. X    {
  469. X        memBytesHandle    hBytes;
  470. X        Size            grow;
  471. X
  472. X        if (! (hBytes = (memBytesHandle) GetResource('memB', membID)))
  473. X            note(nilHandleErr, 0, "\pNil Memory Handle");
  474. X
  475. X        pBytes = *hBytes;
  476. X
  477. X        if (MaxMem(&grow) < pBytes->memPreempt)
  478. X            note(memFullErr, 0, "\pMore Memory Required\rTry adding 16k");
  479. X
  480. X        memActivity = pBytes->memCleanup;        /* force initial cleanup */
  481. X    }
  482. X
  483. X    /* get the I/O buffer */
  484. X    if (! (pIOBuf = NewPtr(pBytes->memIOBuf)))
  485. X        note(memFullErr, 0, "\pNil I/O Pointer");
  486. X}
  487. X
  488. X/* align a window-related template to the main screen */
  489. Xstatic Handle
  490. XalignTemplate(ResType rezType, short rezID, short vOff, short vDenom, Point *pPt)
  491. X{
  492. X    Handle    rtnHnd;
  493. X    Rect    *pRct;
  494. X
  495. X    vOff += GetMBarHeight();
  496. X
  497. X    if (! (rtnHnd = GetResource(rezType, rezID)))
  498. X        note(nilHandleErr, 0, "\pNil Template Handle");
  499. X
  500. X    pRct = (Rect *) *rtnHnd;
  501. X
  502. X    /* don't move memory while aligning rect */
  503. X    pRct->right -= pRct->left;        /* width */
  504. X    pRct->bottom -= pRct->top;        /* height */
  505. X    pRct->left = (qd.screenBits.bounds.right - pRct->right) / 2;
  506. X    pRct->top = (qd.screenBits.bounds.bottom - pRct->bottom - vOff) / vDenom;
  507. X    pRct->top += vOff;
  508. X    pRct->right += pRct->left;
  509. X    pRct->bottom += pRct->top;
  510. X
  511. X    if (pPt)
  512. X        *pPt = * (Point *) pRct;    /* top left corner */
  513. X
  514. X    return rtnHnd;
  515. X}
  516. X
  517. X/* notification completion routine */
  518. Xpascal void
  519. XnmCompletion(NMRec * pNMR)
  520. X{
  521. X    (void) NMRemove(pNMR);
  522. X
  523. X    (* (short *) (pNMR->nmPending))--;    /* decrement pending note level */
  524. X    ((notifPtr) pNMR)->nmDispose = 1;    /* allow DisposPtr() */
  525. X}
  526. X
  527. X/*
  528. X * handle errors inside of note().  the error message is appended to the
  529. X * given message but on a separate line and must fit within nmBufSize.
  530. X */
  531. Xstatic void
  532. XnoteErrorMessage(unsigned char *msg, unsigned char *errMsg)
  533. X{
  534. X    short    i = nmt.nmBuf[0] + 1;        /* insertion point */
  535. X
  536. X    BlockMove(&msg[1], &nmt.nmBuf[i], msg[0]);
  537. X    nmt.nmBuf[i + msg[0]] = '\r';
  538. X    nmt.nmBuf[0] += (msg[0] + 1);
  539. X
  540. X    note(memFullErr, 0, errMsg);
  541. X}
  542. X
  543. X/*
  544. X * display messages using Notification Manager or an alert.
  545. X * no run-length checking is done.  the messages are created to fit
  546. X * in the allocated space (nmBufSize and aboutBufSize).
  547. X */
  548. Xstatic void
  549. Xnote(short errorSignal, short alertID, unsigned char *msg)
  550. X{
  551. X    if (! errorSignal)
  552. X    {
  553. X        Size    grow;
  554. X
  555. X        if (MaxMem(&grow) < pBytes->memAbort)
  556. X            noteErrorMessage(msg, "\pOut of Memory");
  557. X    }
  558. X
  559. X    if (errorSignal || !in.Front)
  560. X    {
  561. X        notifPtr    pNMR;
  562. X        short        i = nmt.nmBuf[0] + 1;    /* insertion point */
  563. X
  564. X        if (errorSignal)        /* use notification template */
  565. X        {
  566. X            pNMR = &nmt;
  567. X
  568. X            /* we're going to abort so add in this prefix */
  569. X            BlockMove("Abort: ", &nmt.nmBuf[i], 7);
  570. X            i += 7;
  571. X            nmt.nmBuf[0] += 7;
  572. X        }
  573. X        else                    /* allocate a notification record */
  574. X        {
  575. X            if (! (pNMR = (notifPtr) NewPtr(sizeof(notifRec))))
  576. X                noteErrorMessage(msg, "\pNil New Pointer");
  577. X
  578. X            /* initialize it */
  579. X            *pNMR = nmt;
  580. X            pNMR->nmr.nmStr = (StringPtr) &(pNMR->nmBuf);
  581. X
  582. X            /* update the notification queue */
  583. X            if (!pNMQ)
  584. X                pNMQ = pNMR;
  585. X            else
  586. X            {
  587. X                notifPtr    pNMX;
  588. X
  589. X                /* find the end of the queue */
  590. X                for (pNMX = pNMQ; pNMX->nmNext; pNMX = pNMX->nmNext)
  591. X                    ;
  592. X
  593. X                pNMX->nmNext = pNMR;
  594. X            }
  595. X        }
  596. X
  597. X        /* concatenate the message */
  598. X        BlockMove(&msg[1], &((pNMR->nmBuf)[i]), msg[0]);
  599. X        (pNMR->nmBuf)[0] += msg[0];
  600. X
  601. X        in.Notify++;            /* increase note pending level */
  602. X
  603. X        NMInstall((NMRec *) pNMR);
  604. X
  605. X        if (errorSignal)
  606. X            cooldown();
  607. X
  608. X        return;
  609. X    }
  610. X
  611. X    /* in front and no error so use an alert */
  612. X    ParamText(msg, "\p", "\p", "\p");
  613. X    (void) Alert(alertID, (ModalFilterProcPtr) 0L);
  614. X    ResetAlrtStage();
  615. X
  616. X    memActivity++;
  617. X}
  618. X
  619. Xstatic void
  620. XadjustGUI()
  621. X{
  622. X    static short    oldMenubar = mbar_Init;    /* force initial update */
  623. X    short            newMenubar;
  624. X    WindowPeek        frontWindow;
  625. X
  626. X    /* oldCursor is external so it can be reset in endRecover() */
  627. X    static short    newCursor = curs_Init;
  628. X    unsigned long    timeNow;
  629. X    short            useArrow;
  630. X
  631. X    /* adjust menubar 1st */
  632. X    newMenubar = in.Recover ? mbarRecover : mbarAppl;
  633. X
  634. X    /* desk accessories take precedence */
  635. X    if (frontWindow = (WindowPeek) FrontWindow())
  636. X        if (frontWindow->windowKind < 0)
  637. X            newMenubar = mbarDA;
  638. X
  639. X    if (newMenubar != oldMenubar)
  640. X    {
  641. X        /* adjust menus */
  642. X        switch (oldMenubar = newMenubar)
  643. X        {
  644. X        case mbarAppl:
  645. X            EnableItem(mHnd[menuFile], mitmOpen);
  646. X            SetItemMark(mHnd[menuFile], mitmOpen, noMark);
  647. X            DisableItem(mHnd[menuFile], mitmClose_DA);
  648. X            DisableItem(mHnd[menuEdit], 0);
  649. X            break;
  650. X
  651. X        case mbarRecover:
  652. X            DisableItem(mHnd[menuFile], mitmOpen);
  653. X            SetItemMark(mHnd[menuFile], mitmOpen, checkMark);
  654. X            DisableItem(mHnd[menuFile], mitmClose_DA);
  655. X            DisableItem(mHnd[menuEdit], 0);
  656. X            break;
  657. X
  658. X        case mbarDA:
  659. X            DisableItem(mHnd[menuFile], mitmOpen);
  660. X            EnableItem(mHnd[menuFile], mitmClose_DA);
  661. X            EnableItem(mHnd[menuEdit], 0);
  662. X            break;
  663. X        }
  664. X
  665. X        DrawMenuBar();
  666. X    }
  667. X
  668. X    /* now adjust the cursor */
  669. X    if (useArrow = (!in.Recover || (newMenubar == mbarDA)))
  670. X        newCursor = curs_Init;
  671. X    else if ((timeNow = TickCount()) >= timeCursor)        /* spin cursor */
  672. X    {
  673. X        timeCursor = timeNow + CURS_FRAME;
  674. X        if (++newCursor >= curs_Total)
  675. X            newCursor = 0;
  676. X    }
  677. X
  678. X    if (newCursor != oldCursor)
  679. X    {
  680. X        oldCursor = newCursor;
  681. X
  682. X        SetCursor(useArrow ? &qd.arrow : cPtr[newCursor]);
  683. X    }
  684. X}
  685. X
  686. Xstatic void
  687. XadjustMemory()
  688. X{
  689. X    Size        grow;
  690. X
  691. X    memActivity = 0;
  692. X
  693. X    if (MaxMem(&grow) < pBytes->memWarning)
  694. X        note(noErr, alidNote, "\pWarning: Memory is running low");
  695. X
  696. X    (void) ResrvMem((Size) FreeMem());        /* move all handles high */
  697. X}
  698. X
  699. X/* show memory stats: FreeMem, MaxBlock, PurgeSpace, and StackSpace */
  700. Xstatic void
  701. XoptionMemStats()
  702. X{
  703. X    unsigned char    *pFormat = "\pFree:#k  Max:#k  Purge:#k  Stack:#k";
  704. X    char            *pSub = "#";        /* not a pascal string */
  705. X    unsigned char    nBuf[16];
  706. X    long            nStat, contig;
  707. X    Handle            strHnd;
  708. X    long            nOffset;
  709. X    short            i;
  710. X
  711. X    if (wnEvt.modifiers & shiftKey)
  712. X        adjustMemory();
  713. X
  714. X    if (! (strHnd = NewHandle((Size) 128)))
  715. X    {
  716. X        note(noErr, alidNote, "\pOops: Memory stats unavailable!");
  717. X        return;
  718. X    }
  719. X    
  720. X    SetString((StringHandle) strHnd, pFormat);
  721. X    nOffset = 1L;
  722. X
  723. X    for (i = 1; i <= 4; i++)
  724. X    {
  725. X        /* get the replacement number stat */
  726. X        switch (i)
  727. X        {
  728. X        case 1: nStat = FreeMem();                break;
  729. X        case 2: nStat = MaxBlock();                break;
  730. X        case 3: PurgeSpace(&nStat, &contig);    break;
  731. X        case 4: nStat = StackSpace();            break;
  732. X        }
  733. X
  734. X        NumToString((nStat >> 10), * (Str255 *) &nBuf);
  735. X
  736. X        **strHnd += nBuf[0] - 1;
  737. X        nOffset = Munger(strHnd, nOffset, (Ptr) pSub, 1L, (Ptr) &nBuf[1], nBuf[0]);
  738. X    }
  739. X
  740. X    MoveHHi(strHnd);
  741. X    HLock(strHnd);
  742. X    note(noErr, alidNote, (unsigned char *) *strHnd);
  743. X    DisposHandle(strHnd);
  744. X}
  745. X
  746. Xstatic void
  747. XMenuEvent(long menuEntry)
  748. X{
  749. X    short menuID = HiWord(menuEntry);
  750. X    short menuItem = LoWord(menuEntry);
  751. X
  752. X    switch (menuID)
  753. X    {
  754. X    case muidApple:
  755. X        switch (menuItem)
  756. X        {
  757. X        case mitmAbout:
  758. X            if (wnEvt.modifiers & optionKey)
  759. X                optionMemStats();
  760. X            /* fall thru */
  761. X        case mitmHelp:
  762. X            note(noErr, (alertAppleMenu + menuItem), aboutBuf);
  763. X            break;
  764. X
  765. X        default:    /* DA's or apple menu items */
  766. X            {
  767. X                unsigned char    daName[32];
  768. X
  769. X                GetItem(mHnd[menuApple], menuItem, * (Str255 *) &daName);
  770. X                (void) OpenDeskAcc(daName);
  771. X
  772. X                memActivity++;
  773. X            }
  774. X            break;
  775. X        }
  776. X        break;
  777. X
  778. X    case muidFile:
  779. X        switch (menuItem)
  780. X        {
  781. X        case mitmOpen:
  782. X            beginRecover();
  783. X            break;
  784. X
  785. X        case mitmClose_DA:
  786. X            {
  787. X                WindowPeek    frontWindow;
  788. X                short        refNum;
  789. X
  790. X                if (frontWindow = (WindowPeek) FrontWindow())
  791. X                    if ((refNum = frontWindow->windowKind) < 0)
  792. X                        CloseDeskAcc(refNum);
  793. X
  794. X                memActivity++;
  795. X            }
  796. X            break;
  797. X
  798. X        case mitmQuit:
  799. X            cooldown();
  800. X            break;
  801. X        }
  802. X        break;
  803. X
  804. X    case muidEdit:
  805. X        (void) SystemEdit(menuItem - 1);
  806. X        break;
  807. X    }
  808. X
  809. X    HiliteMenu(0);
  810. X}
  811. X
  812. Xstatic void
  813. XeventLoop()
  814. X{
  815. X    short    wneMask = (in.Front ? everyEvent : (osMask + updateMask));
  816. X    long    wneSleep = (in.Front ? 0L : 3L);
  817. X
  818. X    while (1)
  819. X    {
  820. X        if (in.Front)
  821. X            adjustGUI();
  822. X
  823. X        if (memActivity >= pBytes->memCleanup)
  824. X            adjustMemory();
  825. X
  826. X        (void) WaitNextEvent(wneMask, &wnEvt, wneSleep, (RgnHandle) 0L);
  827. X
  828. X        if (in.Dialog)
  829. X            (void) IsDialogEvent(&wnEvt);
  830. X
  831. X        switch (wnEvt.what)
  832. X        {
  833. X        case osEvt:
  834. X            if (((wnEvt.message & osEvtMessageMask) >> 24) == suspendResumeMessage)
  835. X            {
  836. X                in.Front = (wnEvt.message & resumeFlag);
  837. X                wneMask = (in.Front ? everyEvent : (osMask + updateMask));
  838. X                wneSleep = (in.Front ? 0L : 3L);
  839. X            }
  840. X            break;
  841. X
  842. X        case nullEvent:
  843. X            /* adjust the FIFO notification queue */
  844. X            if (pNMQ && pNMQ->nmDispose)
  845. X            {
  846. X                notifPtr pNMX = pNMQ->nmNext;
  847. X
  848. X                DisposPtr((Ptr) pNMQ);
  849. X                pNMQ = pNMX;
  850. X
  851. X                memActivity++;
  852. X            }
  853. X
  854. X            if (in.Recover)
  855. X                continueRecover();
  856. X            break;
  857. X
  858. X        case mouseDown:
  859. X            {
  860. X                WindowPtr    whichWindow;
  861. X                
  862. X                switch(FindWindow( wnEvt . where , &whichWindow))
  863. X                {
  864. X                case inMenuBar:
  865. X                    MenuEvent(MenuSelect( wnEvt . where ));
  866. X                    break;
  867. X
  868. X                case inSysWindow:
  869. X                    SystemClick(&wnEvt, whichWindow);
  870. X                    break;
  871. X
  872. X                case inDrag:
  873. X                    {
  874. X                        Rect    boundsRect = qd.screenBits.bounds;
  875. X                        Point    offsetPt;
  876. X
  877. X                        InsetRect(&boundsRect, 4, 4);
  878. X                        boundsRect.top += GetMBarHeight();
  879. X
  880. X                        DragWindow(whichWindow, * ((Point *) &wnEvt.where), &boundsRect);
  881. X
  882. X                        boundsRect = whichWindow->portRect;
  883. X                        offsetPt = * (Point *) &(whichWindow->portBits.bounds);
  884. X                        OffsetRect(&boundsRect, -offsetPt.h, -offsetPt.v);
  885. X
  886. X                        * (Rect *) *thermoTHnd = boundsRect;
  887. X                    }
  888. X                    break;
  889. X                }
  890. X            }
  891. X            break;
  892. X
  893. X        case keyDown:
  894. X            {
  895. X                char    key = (wnEvt.message & charCodeMask);
  896. X
  897. X                if (wnEvt.modifiers & cmdKey)
  898. X                {
  899. X                    if (key == '.')
  900. X                    {
  901. X                        if (in.Recover)
  902. X                        {
  903. X                            endRecover();
  904. X                            note(noErr, alidNote, "\pSorry: Recovery aborted");
  905. X                        }
  906. X                    }
  907. X                    else
  908. X                        MenuEvent(MenuKey(key));
  909. X                }
  910. X            }
  911. X            break;
  912. X
  913. X        /* without windows these events belong to our thermometer */
  914. X        case updateEvt:
  915. X        case activateEvt:
  916. X        {
  917. X            DialogPtr    dPtr;
  918. X            short        itemHit;
  919. X
  920. X            (void) DialogSelect(&wnEvt, &dPtr, &itemHit);
  921. X        }
  922. X
  923. X        case diskEvt:
  924. X            if (HiWord(wnEvt.message))
  925. X            {
  926. X                Point    pt = {60, 60};
  927. X
  928. X                (void) DIBadMount(pt, wnEvt.message);
  929. X                DIUnload();
  930. X
  931. X                memActivity++;
  932. X            }
  933. X            break;
  934. X        }            /* switch (wnEvt.what) */
  935. X    }                /* while (1) */
  936. X}
  937. X
  938. Xstatic void
  939. Xcooldown()
  940. X{
  941. X    if (in.Recover)
  942. X        endRecover();
  943. X
  944. X    /* wait for pending notifications to complete */
  945. X    while (in.Notify)
  946. X        (void) WaitNextEvent(0, &wnEvt, 3L, (RgnHandle) 0L);
  947. X
  948. X    ExitToShell();
  949. X}
  950. X
  951. X/* draw the progress thermometer and frame.  1 level <=> 1 horiz. pixel */
  952. Xpascal void
  953. XdrawThermo(WindowPtr wPtr, short inum)
  954. X{
  955. X    itemizeThermo(drawItem);
  956. X}
  957. X
  958. X/* manage progress thermometer dialog */
  959. Xstatic void
  960. XitemizeThermo(short itemMode)
  961. X{
  962. X    short    iTyp, iTmp;
  963. X    Handle    iHnd;
  964. X    Rect    iRct;
  965. X
  966. X    GetDItem(DLGTHM, uitmThermo, &iTyp, &iHnd, &iRct);
  967. X
  968. X    switch(itemMode)
  969. X    {
  970. X    case initItem:
  971. X        SetDItem(DLGTHM, uitmThermo, iTyp, (Handle) drawThermo, &iRct);
  972. X        break;
  973. X
  974. X    case invalItem:
  975. X        {
  976. X            GrafPtr    oldPort;
  977. X
  978. X            GetPort(&oldPort);
  979. X            SetPort(GRFTHM);
  980. X
  981. X            InsetRect(&iRct, 1, 1);
  982. X            InvalRect(&iRct);
  983. X
  984. X            SetPort(oldPort);
  985. X        }
  986. X        break;
  987. X
  988. X    case drawItem:
  989. X            FrameRect(&iRct);
  990. X            InsetRect(&iRct, 1, 1);
  991. X
  992. X            iTmp = iRct.right;
  993. X            iRct.right = iRct.left + in.Recover;
  994. X            PaintRect(&iRct);
  995. X
  996. X            iRct.left = iRct.right;
  997. X            iRct.right = iTmp;
  998. X            EraseRect(&iRct);
  999. X        break;
  1000. X    }
  1001. X}
  1002. X
  1003. X/* show only <pid-plname>.0 files in get file dialog */
  1004. Xpascal Boolean
  1005. XbasenameFileFilter(ParmBlkPtr pPB)
  1006. X{
  1007. X    unsigned char    *pC;
  1008. X
  1009. X    if (! (pC = (unsigned char *) pPB->fileParam.ioNamePtr))
  1010. X        return true;
  1011. X
  1012. X    if ((*pC < 4) || (*pC > 28))                        /* save/ 1name .0 */
  1013. X        return true;
  1014. X
  1015. X    if ((pC[*pC - 1] == '.') && (pC[*pC] == '0'))        /* bingo! */
  1016. X        return false;
  1017. X
  1018. X    return true;
  1019. X}
  1020. X
  1021. Xstatic void
  1022. XbeginRecover()
  1023. X{
  1024. X    SFTypeList        levlType = {'LEVL'};
  1025. X    SFReply            sfGetReply;
  1026. X
  1027. X    SFGetFile(sfGetWhere, "\p", &basenameFileFilter, 1, levlType,
  1028. X                (DlgHookProcPtr) 0L, &sfGetReply);
  1029. X
  1030. X    memActivity++;
  1031. X
  1032. X    if (! sfGetReply.good)
  1033. X        return;
  1034. X
  1035. X    /* get volume (working directory) refnum, basename, and directory i.d. */
  1036. X    vRefNum = sfGetReply.vRefNum;
  1037. X    BlockMove(sfGetReply.fName, lock, sfGetReply.fName[0] + 1);
  1038. X    {
  1039. X        static CInfoPBRec    catInfo;
  1040. X
  1041. X        catInfo.hFileInfo.ioNamePtr = (StringPtr) sfGetReply.fName;
  1042. X        catInfo.hFileInfo.ioVRefNum = sfGetReply.vRefNum;
  1043. X        catInfo.hFileInfo.ioDirID = 0L;
  1044. X
  1045. X        if (PBGetCatInfoSync(&catInfo))
  1046. X        {
  1047. X            note(noErr, alidNote, "\pSorry: Bad File Info");
  1048. X            return;
  1049. X        }
  1050. X
  1051. X        dirID = catInfo.hFileInfo.ioFlParID;
  1052. X    }
  1053. X
  1054. X    /* open the progress thermometer dialog */
  1055. X    (void) GetNewDialog(dlogProgress, (Ptr) &dlgThermo, (WindowPtr) -1L);
  1056. X    if (ResError() || MemError())
  1057. X        note(noErr, alidNote, "\pOops: Progress thermometer unavailable");
  1058. X    else
  1059. X    {
  1060. X        in.Dialog = 1;
  1061. X        memActivity++;
  1062. X
  1063. X        itemizeThermo(initItem);
  1064. X
  1065. X        ShowWindow(WNDTHM);
  1066. X    }
  1067. X
  1068. X    timeCursor = TickCount() + CURS_LATENT;
  1069. X    saveRefNum = gameRefNum = levRefNum = -1;
  1070. X    in.Recover = 1;
  1071. X}
  1072. X
  1073. Xstatic void
  1074. XcontinueRecover()
  1075. X{
  1076. X    restore_savefile();
  1077. X
  1078. X    /* update the thermometer */
  1079. X    if (in.Dialog && ! (in.Recover % 4))
  1080. X        itemizeThermo(invalItem);
  1081. X
  1082. X    if (in.Recover <= MAX_RECOVER_COUNT)
  1083. X        return;
  1084. X
  1085. X    endRecover();
  1086. X
  1087. X    if (saveRezStrings())
  1088. X        return;
  1089. X
  1090. X    note(noErr, alidNote, "\pOK: Recovery succeeded");
  1091. X}
  1092. X
  1093. X/* no messages from here (since we might be quitting) */
  1094. Xstatic void
  1095. XendRecover()
  1096. X{
  1097. X    in.Recover = 0;
  1098. X
  1099. X    oldCursor = curs_Init;
  1100. X    SetCursor(&qd.arrow);
  1101. X
  1102. X    /* clean up abandoned files */
  1103. X    if (gameRefNum >= 0)
  1104. X        (void) FSClose(gameRefNum);
  1105. X
  1106. X    if (levRefNum >= 0)
  1107. X        (void) FSClose(levRefNum);
  1108. X
  1109. X    if (saveRefNum >= 0)
  1110. X    {
  1111. X        (void) FSClose(saveRefNum);
  1112. X        (void) FlushVol((StringPtr) 0L, vRefNum);
  1113. X        /* its corrupted so trash it ... */
  1114. X        (void) HDelete(vRefNum, dirID, savename);
  1115. X    }
  1116. X
  1117. X    saveRefNum = gameRefNum = levRefNum = -1;
  1118. X
  1119. X    /* close the progress thermometer dialog */
  1120. X    in.Dialog = 0;
  1121. X    CloseDialog(DLGTHM);
  1122. X    DisposHandle(dlgThermo.items);
  1123. X    memActivity++;
  1124. X}
  1125. X
  1126. X/* add friendly, non-essential resource strings to save file */
  1127. Xstatic short
  1128. XsaveRezStrings()
  1129. X{
  1130. X    short            sRefNum;
  1131. X    StringHandle    strHnd;
  1132. X    short            i, rezID;
  1133. X    unsigned char    *plName;
  1134. X
  1135. X    HCreateResFile(vRefNum, dirID, savename);
  1136. X
  1137. X    sRefNum = HOpenResFile(vRefNum, dirID, savename, fsRdWrPerm);
  1138. X    if (sRefNum <= 0)
  1139. X    {
  1140. X        note(noErr, alidNote, "\pOK: Minor resource map error");
  1141. X        return 1;
  1142. X    }
  1143. X
  1144. X    /* savename and hpid get mutilated here... */
  1145. X    plName = savename + 5;                /* save/ */
  1146. X    *savename -= 5;
  1147. X    do
  1148. X    {
  1149. X        plName++;
  1150. X        (*savename)--;
  1151. X        hpid /= 10L;
  1152. X    }
  1153. X    while (hpid);
  1154. X    *plName = *savename;
  1155. X
  1156. X    for (i = 1; i <= 2; i++)
  1157. X    {
  1158. X        switch (i)
  1159. X        {
  1160. X        case 1:
  1161. X            rezID = PLAYER_NAME_RES_ID;
  1162. X            strHnd = NewString(* (Str255 *) plName);
  1163. X            break;
  1164. X
  1165. X        case 2:
  1166. X            rezID = APP_NAME_RES_ID;
  1167. X            strHnd = NewString(* (Str255 *) "\pNetHack");
  1168. X            break;
  1169. X        }
  1170. X
  1171. X        if (! strHnd)
  1172. X        {
  1173. X            note(noErr, alidNote, "\pOK: Minor \'STR \' resource error");
  1174. X            CloseResFile(sRefNum);
  1175. X            return 1;
  1176. X        }
  1177. X
  1178. X        /* should check for errors... */
  1179. X        AddResource((Handle) strHnd, 'STR ', rezID, * (Str255 *) "\p");
  1180. X    }
  1181. X
  1182. X    memActivity++;
  1183. X
  1184. X    /* should check for errors... */
  1185. X    CloseResFile(sRefNum);
  1186. X    return 0;
  1187. X}
  1188. X
  1189. Xstatic void
  1190. Xset_levelfile_name(long lev)
  1191. X{
  1192. X    unsigned char    *tf;
  1193. X
  1194. X    /* find the dot.  this is guaranteed to happen. */
  1195. X    for (tf = (lock + *lock); *tf != '.'; tf--, lock[0]--)
  1196. X        ;
  1197. X
  1198. X    /* append the level number string (pascal) */
  1199. X    if (tf > lock)
  1200. X    {
  1201. X        NumToString(lev, * (Str255 *) tf);
  1202. X        lock[0] += *tf;
  1203. X        *tf = '.';
  1204. X    }
  1205. X    else    /* huh??? */
  1206. X    {
  1207. X        endRecover();
  1208. X        note(noErr, alidNote, "\pSorry: File Name Error");
  1209. X    }
  1210. X}
  1211. X
  1212. Xstatic short
  1213. Xopen_levelfile(long lev)
  1214. X{
  1215. X    OSErr    openErr;
  1216. X    short    fRefNum;
  1217. X
  1218. X    set_levelfile_name(lev);
  1219. X    if (! in.Recover)
  1220. X        return (-1);
  1221. X
  1222. X    if ((openErr = HOpen(vRefNum, dirID, lock, fsRdWrPerm, &fRefNum))
  1223. X            && (openErr != fnfErr))
  1224. X    {
  1225. X        endRecover();
  1226. X        note(noErr, alidNote, "\pSorry: File Open Error");
  1227. X        return (-1);
  1228. X    }
  1229. X
  1230. X    return (openErr ? -1 : fRefNum);
  1231. X}
  1232. X
  1233. Xstatic short
  1234. Xcreate_savefile(unsigned char *savename)
  1235. X{
  1236. X    short    fRefNum;
  1237. X
  1238. X    /* translate savename to a pascal string (in place) */
  1239. X    {
  1240. X        unsigned char    *pC;
  1241. X        short            nameLen;
  1242. X
  1243. X        for (pC = savename; *pC; pC++);
  1244. X
  1245. X        nameLen = pC - savename;
  1246. X
  1247. X        for ( ; pC > savename; pC--)
  1248. X            *pC = *(pC - 1);
  1249. X
  1250. X        *savename = nameLen;
  1251. X    }
  1252. X
  1253. X    if (HCreate(vRefNum, dirID, savename, CREATOR, SAVETYPE)
  1254. X        || HOpen(vRefNum, dirID, savename, fsRdWrPerm, &fRefNum))
  1255. X    {
  1256. X        endRecover();
  1257. X        note(noErr, alidNote, "\pSorry: File Create Error");
  1258. X        return (-1);
  1259. X    }
  1260. X
  1261. X    return fRefNum;
  1262. X}
  1263. X
  1264. Xstatic void
  1265. Xcopy_bytes(short inRefNum, short outRefNum)
  1266. X{
  1267. X    char    *buf = (char *) pIOBuf;
  1268. X    long    bufSiz = pBytes->memIOBuf;
  1269. X
  1270. X    long    nfrom, nto;
  1271. X
  1272. X    do
  1273. X    {
  1274. X        nfrom = read_levelfile(inRefNum, buf, bufSiz);
  1275. X        if (! in.Recover)
  1276. X            return;
  1277. X
  1278. X        nto = write_savefile(outRefNum, buf, nfrom);
  1279. X        if (! in.Recover)
  1280. X            return;
  1281. X
  1282. X        if (nto != nfrom)
  1283. X        {
  1284. X            endRecover();
  1285. X            note(noErr, alidNote, "\pSorry: File Copy Error");
  1286. X            return;
  1287. X        }
  1288. X    }
  1289. X    while (nfrom == bufSiz);
  1290. X}
  1291. X
  1292. Xstatic void
  1293. Xrestore_savefile()
  1294. X{
  1295. X    static long    savelev;
  1296. X    long        saveTemp, lev;
  1297. X    xchar        levc;
  1298. X
  1299. X    /* level 0 file contains:
  1300. X     *    pid of creating process (ignored here)
  1301. X     *    level number for current level of save file
  1302. X     *    name of save file nethack would have created
  1303. X     *    and game state
  1304. X     */
  1305. X
  1306. X    lev = in.Recover - 1;
  1307. X    if (lev == 0L)
  1308. X    {
  1309. X        gameRefNum = open_levelfile(0L);
  1310. X
  1311. X        if (in.Recover)
  1312. X            (void) read_levelfile(gameRefNum, (Ptr) &hpid, sizeof(hpid));
  1313. X
  1314. X        if (in.Recover)
  1315. X            saveTemp = read_levelfile(gameRefNum, (Ptr) &savelev, sizeof(savelev));
  1316. X
  1317. X        if (in.Recover && (saveTemp != sizeof(savelev)))
  1318. X        {
  1319. X            endRecover();
  1320. X            note(noErr, alidNote, "\pSorry: \"checkpoint\" was not enabled");
  1321. X            return;
  1322. X        }
  1323. X
  1324. X        if (in.Recover)
  1325. X            (void) read_levelfile(gameRefNum, (Ptr) savename, sizeof(savename));
  1326. X
  1327. X        /* save file should contain:
  1328. X         *    current level (including pets)
  1329. X         *    (non-level-based) game state
  1330. X         *    other levels
  1331. X         */
  1332. X        if (in.Recover)
  1333. X            saveRefNum = create_savefile(savename);
  1334. X
  1335. X        if (in.Recover)
  1336. X            levRefNum = open_levelfile(savelev);
  1337. X
  1338. X        if (in.Recover)
  1339. X            copy_bytes(levRefNum, saveRefNum);
  1340. X
  1341. X        if (in.Recover)
  1342. X            close_file(&levRefNum);
  1343. X
  1344. X        if (in.Recover)
  1345. X            unlink_file(lock);
  1346. X
  1347. X        if (in.Recover)
  1348. X            copy_bytes(gameRefNum, saveRefNum);
  1349. X
  1350. X        if (in.Recover)
  1351. X            close_file(&gameRefNum);
  1352. X
  1353. X        if (in.Recover)
  1354. X            set_levelfile_name(0L);
  1355. X
  1356. X        if (in.Recover)
  1357. X            unlink_file(lock);
  1358. X    }
  1359. X    else if (lev != savelev)
  1360. X    {
  1361. X        levRefNum = open_levelfile(lev);
  1362. X        if (levRefNum >= 0)
  1363. X        {
  1364. X            /* any or all of these may not exist */
  1365. X            levc = (xchar) lev;
  1366. X
  1367. X            (void) write_savefile(saveRefNum, (Ptr) &levc, sizeof(levc));
  1368. X
  1369. X            if (in.Recover)
  1370. X                copy_bytes(levRefNum, saveRefNum);
  1371. X
  1372. X            if (in.Recover)
  1373. X                close_file(&levRefNum);
  1374. X
  1375. X            if (in.Recover)
  1376. X                unlink_file(lock);
  1377. X        }
  1378. X    }
  1379. X
  1380. X    if (in.Recover == MAX_RECOVER_COUNT)
  1381. X        close_file(&saveRefNum);
  1382. X
  1383. X    if (in.Recover)
  1384. X        in.Recover++;
  1385. X}
  1386. X
  1387. Xstatic long
  1388. Xread_levelfile(short rdRefNum, Ptr bufPtr, long count)
  1389. X{
  1390. X    OSErr    rdErr;
  1391. X    long    rdCount = count;
  1392. X
  1393. X    if ((rdErr = FSRead(rdRefNum, &rdCount, bufPtr)) && (rdErr != eofErr))
  1394. X    {
  1395. X        endRecover();
  1396. X        note(noErr, alidNote, "\pSorry: File Read Error");
  1397. X        return (-1L);
  1398. X    }
  1399. X
  1400. X    return rdCount;
  1401. X}
  1402. X
  1403. Xstatic long
  1404. Xwrite_savefile(short wrRefNum, Ptr bufPtr, long count)
  1405. X{
  1406. X    long    wrCount = count;
  1407. X
  1408. X    if (FSWrite(wrRefNum, &wrCount, bufPtr))
  1409. X    {
  1410. X        endRecover();
  1411. X        note(noErr, alidNote, "\pSorry: File Write Error");
  1412. X        return (-1L);
  1413. X    }
  1414. X
  1415. X    return wrCount;
  1416. X}
  1417. X
  1418. Xstatic void
  1419. Xclose_file(short *pFRefNum)
  1420. X{
  1421. X    if (FSClose(*pFRefNum) || FlushVol((StringPtr) 0L, vRefNum))
  1422. X    {
  1423. X        endRecover();
  1424. X        note(noErr, alidNote, "\pSorry: File Close Error");
  1425. X        return;
  1426. X    }
  1427. X
  1428. X    *pFRefNum = -1;
  1429. X}
  1430. X
  1431. Xstatic void
  1432. Xunlink_file(unsigned char *filename)
  1433. X{
  1434. X    if (HDelete(vRefNum, dirID, filename))
  1435. X    {
  1436. X        endRecover();
  1437. X        note(noErr, alidNote, "\pSorry: File Delete Error");
  1438. X        return;
  1439. X    }
  1440. X}
  1441. X#endif
  1442. END_OF_FILE
  1443. if test 30445 -ne `wc -c <'sys/mac/mrecover.c'`; then
  1444.     echo shar: \"'sys/mac/mrecover.c'\" unpacked with wrong size!
  1445. fi
  1446. # end of 'sys/mac/mrecover.c'
  1447. if test -f 'sys/os2/Install.os2' -a "${1}" != "-c" ; then 
  1448.   echo shar: Renaming existing file \"'sys/os2/Install.os2'\" to \"'sys/os2/Install.os2.orig'\"
  1449.   mv -f 'sys/os2/Install.os2' 'sys/os2/Install.os2.orig'
  1450. fi
  1451. echo shar: Extracting \"'sys/os2/Install.os2'\" \(15129 characters\)
  1452. sed "s/^X//" >'sys/os2/Install.os2' <<'END_OF_FILE'
  1453. X             Instructions for compiling and installing NetHack 3.1
  1454. X                               on an OS/2 system
  1455. X             =====================================================
  1456. X                                Timo Hakulinen
  1457. X                          Last revision: 31 May 1993
  1458. X
  1459. X0.  Read this entire file before starting, and come back to the Notes below if
  1460. X    you have any problems.
  1461. X
  1462. X1.  Make sure all the NetHack files are in the appropriate directory
  1463. X    structure.  You should have a top directory (e.g. nh31, or whatever you
  1464. X    like) with subdirectories dat, doc, include, src, util, sys\share,
  1465. X    sys\os2, and win\tty.  You may have other subdirectories under sys and
  1466. X    win, but they will not affect compilation for an OS/2 system.  If you do
  1467. X    not follow this structure, the makefile will not function properly.  The
  1468. X    .c files for the main program belong in src, those for utility programs in
  1469. X    util, and OS/2-specific ones in sys\os2.  All the .h files belong in
  1470. X    include, the documentation in doc, and assorted data files in dat.  There
  1471. X    are also some necessary files in sys\share (pc*.c, random.c, dgn_*.*,
  1472. X    lev_*.*).  A more detailed explanation of the directory structure is found
  1473. X    in file Files, which should be in the top directory.
  1474. X
  1475. X    If you downloaded or ftp'd the sources from a UNIX system, the lines may
  1476. X    end in UNIX-style newlines instead of the carriage return and line feed
  1477. X    pairs used by DOS and OS/2.  You'll have to convert them (with a utility
  1478. X    like Rahul Dhesi's "flip").  Also, every file should end with a carriage
  1479. X    return / line feed pair, because Microsoft C has had a habit of ignoring
  1480. X    the last line of each file otherwise.  Besides, even editing UNIX-style
  1481. X    files with DOS editors is often a royal pain.
  1482. X
  1483. X2.  The makefile for OS/2, Makefile.os2, is found in directory sys\os2.  Copy
  1484. X    it to directory src and rename it Makefile.  From now on, Makefile.os2
  1485. X    will be referred to as "the makefile" in this document.
  1486. X
  1487. X    The makefile supports the following make utilities:
  1488. X
  1489. X    NDMAKE      a public domain make utility for DOS by Don Kneller
  1490. X    NMAKE       make shipped with Microsoft languages and IBM C Set/2
  1491. X    DMAKE       a public domain make for DOS and OS/2 by Dennis Vadura
  1492. X
  1493. X    Both NDMAKE and DMAKE are available at major archive sites.  The
  1494. X    following compilers are supported:
  1495. X
  1496. X    compiler:                           runs in:            compiles for:
  1497. X
  1498. X    Microsoft C 5.1                     DOS / OS/2 1.0-2.x  OS/2 1.x
  1499. X    Microsoft 6.0A (see note 5)         - " -               - " -
  1500. X    IBM C Set/2 1.00, Toolkit/2 2.00    OS/2 2.x            OS/2 2.x
  1501. X    GCC emx 0.8f (see note 6)           OS/2 2.x            OS/2 2.x
  1502. X
  1503. X    Note that code compiled for OS/2 versions 1.0-1.3 runs unmodified in OS/2
  1504. X    versions 2.0 and up.  In principle it should be possible to cross compile
  1505. X    NetHack 3.1 for OS/2 in DOS using NDMAKE and MSC, but this is not
  1506. X    recommended (see note 3).
  1507. X
  1508. X    If you're using some other compiler than one listed above, you will have
  1509. X    to adapt the makefile to your needs.  In particular, change the CC,
  1510. X    CFLAGS, LINK, and LFLAGS macros to your C compiler's and linker's liking.
  1511. X    See the makefile for more information.
  1512. X
  1513. X    If you are going to be constructing Fred Fish's termcap library, you'll
  1514. X    need Makefile.lib in sys\share (see note 4).
  1515. X
  1516. X3.  Go to the include subdirectory.  First edit config.h according to the
  1517. X    comments to match your system and desired set of features.  In particular,
  1518. X    make sure that OS2 is defined, and that UNIX, HACKDIR, and COMPRESS are
  1519. X    *not* defined.  If your compiler is ANSI compliant (like practically all
  1520. X    OS/2 compilers are), it's probable that nothing else needs to be
  1521. X    configured in config.h.  However, if you have VISION_TABLES defined and
  1522. X    get a compilation error while processing vis_tab.c, you may have to
  1523. X    uncomment BRACES too.
  1524. X
  1525. X    Next look at os2conf.h.  This file shouldn't need much changing.  If you
  1526. X    want to use the hardcoded OS/2 system definitions in def_os2.h instead of
  1527. X    the compiler's standard headers, comment out OS2_USESYSHEADERS.  This may
  1528. X    become necessary if you are using a compiler which doesn't come with
  1529. X    proper system headers by default.  In this case you may have to edit the
  1530. X    definitions there, because every compiler has its own way of declaring
  1531. X    the necessary system functions and data structures.  In general you
  1532. X    should prefer the compiler's offerings, if possible.
  1533. X
  1534. X    If you are going to compile the game on an HPFS drive, uncomment OS2_HPFS,
  1535. X    which enables the use of longer file names during compilation.  The
  1536. X    generated executable will only use file names compatible with FAT drives,
  1537. X    however.
  1538. X
  1539. X    If you are using a 32 bit compiler other than GCC emx 0.8f or C Set/2 in
  1540. X    OS/2 2.x, force OS2_32BITAPI to be defined.  Otherwise it is defined only
  1541. X    for the above mentioned compilers.
  1542. X
  1543. X    If you are not going to include random.c, because you are using the
  1544. X    random number generator provided by your compiler, you will need to
  1545. X    comment out RANDOM.
  1546. X
  1547. X    If you want to muck with different termcap settings, uncomment TERMLIB to
  1548. X    enable the use of termcap routines (see note 4).  This is not necessary to
  1549. X    create a fully functional game, however.
  1550. X
  1551. X4.  If you are using another compiler than MSC, GCC, or IBM C Set/2, you may
  1552. X    want to look through system.h in the include directory.  This file matches
  1553. X    the return and parameter types for system calls and library routines with
  1554. X    various flavors of compilers and operating systems.  Leaving this file
  1555. X    alone is unlikely to cause problems, but if you get compile errors with
  1556. X    any functions in the standard library, it's worth checking the
  1557. X    declarations there.
  1558. X
  1559. X5.  If you want to change the high score list behavior, examine the top of
  1560. X    topten.c, in the src directory.  You may want to change the definitions of
  1561. X    PERSMAX, POINTSMIN, and ENTRYMAX.
  1562. X
  1563. X6.  Go to the src directory and edit the top of the makefile.  Be sure that
  1564. X    the directory you want the game installed to actually exists.
  1565. X
  1566. X    You'll need nroff and/or TeX/LaTeX to do the files in doc.  If you don't
  1567. X    have either of these, you can skip it.
  1568. X
  1569. X    If you elected not to use the high quality BSD random number routines by
  1570. X    commenting out RANDOM in os2conf.h, comment out (or set equal to nothing)
  1571. X    the RANDOM macro in the makefile.
  1572. X
  1573. X    If you elected to use Fred Fish's termcap library (bundled in as
  1574. X    termcap.uu in directory sys\share), you will have to generate termlib.lib
  1575. X    from those sources by typing "make -f makefile.lib termlib.lib".  You must
  1576. X    set the TERMLIB option in the makefile to link the resulting termlib.lib
  1577. X    into the game.
  1578. X
  1579. X    If you are recompiling after patching your sources, or if you got your
  1580. X    files from somewhere other than the official distribution, "touch
  1581. X    makedefs.c" to ensure that certain files (onames.h and pm.h) are remade,
  1582. X    lest potentially troublesome time stamps fool make.
  1583. X
  1584. X    If you have lex and yacc programs, or the equivalent flex and bison
  1585. X    programs, you can set up the makefile to generate the appropriate .h and
  1586. X    .c files from their .l and .y counterparts whenever you recompile.  This
  1587. X    is done by changing the do_yacc and do_lex targets in the makefile to
  1588. X    depend on targets yacc_act and lex_act instead of yacc_cpy and lex_cpy.
  1589. X    Otherwise the makefile will copy pre-generated yacc and lex output files
  1590. X    dgn_*.* and lev_*.* from directory sys\share to util and include.
  1591. X
  1592. X    Now, enter "make all", and take a siesta; your computer will be occupied
  1593. X    for a fair amount of time.  If all goes well, you will get an executable.
  1594. X
  1595. X7.  All the support data files should have been copied to the game directory
  1596. X    by the make process.  Here is the complete list in alphabetical order of
  1597. X    all the files that should have gotten there during a full build:
  1598. X
  1599. X    A-filla.lev    A-fillb.lev    A-goal.lev     A-locate.lev   A-start.lev
  1600. X    B-filla.lev    B-fillb.lev    B-goal.lev     B-locate.lev   B-start.lev
  1601. X    C-filla.lev    C-fillb.lev    C-goal.lev     C-locate.lev   C-start.lev
  1602. X    E-filla.lev    E-fillb.lev    E-goal.lev     E-locate.lev   E-start.lev
  1603. X    H-filla.lev    H-fillb.lev    H-goal.lev     H-locate.lev   H-start.lev
  1604. X    K-filla.lev    K-fillb.lev    K-goal.lev     K-locate.lev   K-start.lev
  1605. X    P-filla.lev    P-fillb.lev    P-goal.lev     P-locate.lev   P-start.lev
  1606. X    R-filla.lev    R-fillb.lev    R-goal.lev     R-locate.lev   R-start.lev
  1607. X    S-filla.lev    S-fillb.lev    S-goal.lev     S-locate.lev   S-start.lev
  1608. X    T-filla.lev    T-fillb.lev    T-goal.lev     T-locate.lev   T-start.lev
  1609. X    V-filla.lev    V-fillb.lev    V-goal.lev     V-locate.lev   V-start.lev
  1610. X    W-filla.lev    W-fillb.lev    W-goal.lev     W-locate.lev   W-start.lev
  1611. X    air.lev        asmodeus.lev   astral.lev     baalz.lev      bigroom.lev
  1612. X    castle.lev     cmdhelp        data           dungeon        earth.lev
  1613. X    fakewiz1.lev   fakewiz2.lev   fire.lev       help           hh
  1614. X    history        juiblex.lev    knox.lev       license        medusa-1.lev
  1615. X    medusa-2.lev   mine_end.lev   minefill.lev   minetown.lev   nethack.cmd
  1616. X    nethack.cnf    nethack.exe    nethack.ico    opthelp        options
  1617. X    oracle.lev     oracles        orcus.lev      quest.dat      recover.exe
  1618. X    rumors         sanctum.lev    tower1.lev     tower2.lev     tower3.lev
  1619. X    valley.lev     water.lev      wizard1.lev    wizard2.lev    wizard3.lev
  1620. X    wizhelp
  1621. X
  1622. X    Yes.  It's 106 files for a full featured NetHack 3.1.  If any of the files
  1623. X    are missing, try to rerun make.  If that doesn't help, you'll have to try
  1624. X    to decipher the makefile to find out how to manually create the missing
  1625. X    files.  These kinds of troubles shouldn't happen except for two reasons:
  1626. X    You've run out of disk space while compiling or your make utility doesn't
  1627. X    understand the makefile properly for some reason.  In either case, you
  1628. X    should get some warnings from the make, though.
  1629. X
  1630. X    If you have old record, logfile, or news files in the game directory, they
  1631. X    are not overwritten.  Of course, old records from NetHack 3.0 are not
  1632. X    worth keeping with 3.1, since these games are really quite different.
  1633. X
  1634. X    Edit file nethack.cnf in the game directory to reflect your particular
  1635. X    setup and personal preferences, following the comments there.  More info
  1636. X    about settable options can be found in the file opthelp and the guidebook.
  1637. X
  1638. X    If you compiled in the TERMLIB feature, also move the sys\share\termcap
  1639. X    file to your game directory.
  1640. X
  1641. X8.  If you'll be running NetHack from a different subdirectory, you will want
  1642. X    to "set HACKDIR=c:\games\nh31" (or whatever directory you want to use).
  1643. X    Add it to your config.sys, if you'll be playing often.
  1644. X
  1645. X    You can also create a special NetHack entry in your Presentation Manager /
  1646. X    Workplace Shell desktop.  This will use the included NetHack icon.
  1647. X    The following is a sample program description for OS/2 1.3 desktop, but
  1648. X    it's similar for OS/2 2.0:
  1649. X
  1650. X    Program title:          NetHack 3.1
  1651. X    Path and file name:     c:\games\nh31\nethack.cmd
  1652. X    Parameters:
  1653. X    Working directory:      c:\games\nh31
  1654. X    Program type:           OS/2 Full screen
  1655. X
  1656. X    Naturally you must fill in your own game directory and parameters if you
  1657. X    want to set any.  The program type can be either OS/2 Full screen or OS/2
  1658. X    Windowed.  Note that you should set the executable path to use the .cmd
  1659. X    file generated by the makefile.  This file generates an extra pause after
  1660. X    the program exit, because otherwise you wouldn't get to see the high score
  1661. X    list upon quitting due to PM/WPS automatically closing the program window.
  1662. X    When starting NetHack normally from OS/2 command prompt, the command
  1663. X    processor starts nethack.exe instead, so no extra pause is generated.
  1664. X
  1665. X9.  If you want to clear up the temporary files and objects created by the
  1666. X    compilation process, you may issue "make spotless".  This will return your
  1667. X    source tree to near-distribution condition.  Naturally, it will not affect
  1668. X    your newly built game files in any way.
  1669. X
  1670. X10. Play NetHack.  If it works, you're done!
  1671. X
  1672. X
  1673. XNotes
  1674. X-----
  1675. X
  1676. X1)  Save-files and bones-files from previous versions will not work with
  1677. X    NetHack 3.1.  Don't bother trying to keep them.
  1678. X
  1679. X2)  To install an update of NetHack after changing something, enter "make"
  1680. X    from the src directory.  If you add, delete, or reorder monsters or
  1681. X    objects, or you change the format of saved level files, delete any save
  1682. X    and bones files.  (Trying to use such files sometimes produces amusing
  1683. X    confusions on the game's part, but usually crashes.)
  1684. X
  1685. X3)  When cross-compiling for OS/2 in DOS, NDMAKE is the best choice because it
  1686. X    requires the least RAM for itself.  Note however, that cross-compilation
  1687. X    in DOS is discouraged, because it is considered obsolete (OS/2 is really
  1688. X    a much better place to compile).  If you still want to try, here are some
  1689. X    suggestions:
  1690. X
  1691. X    During linking, Microsoft linker will need temporary storage space.  Make
  1692. X    sure you have about 1 MB of free disk where ever you have defined your
  1693. X    temporary storage.  It is also a good idea to compile with as much free
  1694. X    RAM as possible.  It may otherwise get crowded with the bigger, more
  1695. X    complex source files (compiler bombs with "out of heap space" or similar).
  1696. X    If this happens, strip your configuration, zap TSR's, get a better memory
  1697. X    manager etc.
  1698. X
  1699. X4)  The file sys\share\termcap.uu is the fixed version of the Fred Fish
  1700. X    termcap library.  You will need to run a uudecode utility on it to
  1701. X    generate the file termcap.zip.  termcap.zip contains several files of
  1702. X    termcap routines.  Using them with NetHack involves very little knowledge
  1703. X    of the UNIX concept of a termcap database; mostly you need to know enough
  1704. X    to set a TERM environment variable.  You can unzip termcap.zip in the
  1705. X    sys\share directory, but if you are going to use it, it is probably best
  1706. X    to unzip a copy in the src directory.  That way you will not miss copying
  1707. X    any files over.  Wherever you unzip it, get rid of the included makefile
  1708. X    since a better version has been provided as Makefile.lib.  After creating
  1709. X    the termcap library file termlib.lib, copy it to src before compiling the
  1710. X    game main source.
  1711. X
  1712. X5)  When compiling with MSC 6.0, the maintenance version 6.0A should be used
  1713. X    instead of the original 6.0, which was all too buggy to successfully build
  1714. X    NetHack 3.1.
  1715. X
  1716. X6)  Note that emx 0.8f is the first version of GCC for OS/2 that can properly
  1717. X    compile NetHack.  Earlier versions do not work, because they don't support
  1718. X    the 16 bit API calls of OS/2.
  1719. X
  1720. X    GCC emx 0.8f does not currently work properly when fseek() function is
  1721. X    used with text files.  This is well documented in the compiler's
  1722. X    documentation.  Unfortunately NetHack uses fseek() in several places in
  1723. X    connection with text data.  This means that some help texts may not come
  1724. X    out right, but no serious problems should emerge.
  1725. END_OF_FILE
  1726. if test 15129 -ne `wc -c <'sys/os2/Install.os2'`; then
  1727.     echo shar: \"'sys/os2/Install.os2'\" unpacked with wrong size!
  1728. fi
  1729. # end of 'sys/os2/Install.os2'
  1730. if test -f 'sys/winnt/Install.nt' -a "${1}" != "-c" ; then 
  1731.   echo shar: Renaming existing file \"'sys/winnt/Install.nt'\" to \"'sys/winnt/Install.nt.orig'\"
  1732.   mv -f 'sys/winnt/Install.nt' 'sys/winnt/Install.nt.orig'
  1733. fi
  1734. echo shar: Extracting \"'sys/winnt/Install.nt'\" \(10776 characters\)
  1735. sed "s/^X//" >'sys/winnt/Install.nt' <<'END_OF_FILE'
  1736. X    Copyright (c) NetHack PC Development Team 1990 - 1993.
  1737. X    NetHack may be freely redistributed.  See license for details.
  1738. X        ======================================================
  1739. X        Instructions for compiling and installing
  1740. X         NetHack 3.1 on a Windows NT system
  1741. X        ======================================================
  1742. X         (or, How to make NT NetHack 3.1.2)
  1743. X            Last revision: Apr 16, 1993
  1744. X
  1745. XCredit for the PC versions of NetHack goes to the PC Development team 
  1746. Xconsisting of Norm Meluch, Kevin Smolkowski, Paul Winner and Steve 
  1747. XVanDevender who built on the work of Pierre Martineau, Stephen Spackman, 
  1748. XSteve Creps, Mike Threepoint and Don Kneller.  
  1749. X
  1750. XCredit for the porting of NetHack to Windows NT goes to the NT Porting 
  1751. XTeam started by Michael Allison.
  1752. X
  1753. XThe NT porting team also wishes to thank the following people for
  1754. Xtheir help, testing effort, and suggestions which contributed to the 
  1755. Xcompletion of the first Windows NT port of NetHack: Doug Thompson, 
  1756. XPhil Mills, Scott Murray. 
  1757. X
  1758. XThis first version of NetHack for Windows NT is a tty port utilizing 
  1759. Xthe NT WIN32 Console I/O subsystem.
  1760. X
  1761. X
  1762. XI.  Dispelling the Myths:
  1763. X
  1764. X    Compiling NetHack is not as easy as it sounds, nor as hard as it looks,
  1765. X    however it will behoove you to read this entire file through before
  1766. X    beginning the task.
  1767. X
  1768. X    We have provided the proper makefiles for building NetHack using the
  1769. X    following compilers:
  1770. X
  1771. X    Microsoft Windows NT March 1993 SDK C Compiler.
  1772. X
  1773. X    All the makefiles were created for use with MS NMAKE which
  1774. X    is provided with the Windows NT SDK (Software Development Kit).
  1775. X
  1776. X    You may find it useful to obtain copies of lex (flex) and yacc (bison).
  1777. X    While not strictly necessary to compile nethack, they are required should
  1778. X    you desire to make any changes to the level and dungeon compilers.
  1779. X    Flex and Yacc for NT are available in the "Porting from UNIX to
  1780. X    NT" library on the MSWIN32 Forum on compuserve and other places.
  1781. X
  1782. X    To use the distributed NetHack icon, a version of uudecode is required,
  1783. X    but this is not a necessary step for compiling NT NetHack.
  1784. X
  1785. XII. To compile your copy of NetHack on a Windows NT machine:
  1786. X    (or "just follow these few 'simple' steps outlined below.")
  1787. X
  1788. XSetting Up
  1789. X
  1790. X1.  It almost goes without saying that you should make sure that your tools
  1791. X    are set up and running correctly.
  1792. X
  1793. X2.  Make sure all the NetHack files are in the appropriate directory
  1794. X    structure.  You should have a main directory with subdirectories
  1795. X    dat, doc, include, src, sys\share, sys\winnt, util and win\tty.
  1796. X    Other subdirectories may also be included in your distribution, but
  1797. X    they are not necessary for use with NT.  You can delete them
  1798. X    to save space.
  1799. X
  1800. X    Required Directories for NT:
  1801. X
  1802. X                            top
  1803. X                             |
  1804. X        -------------------------------------------- 
  1805. X        |       |     |        |       |     |     | 
  1806. X       util    dat   doc    include   src   sys   win
  1807. X                                             |     |
  1808. X                                          ------   ---- 
  1809. X                                          |    |      | 
  1810. X                                       share  winnt  tty
  1811. X
  1812. X    Check the file "Files" in your top level directory for an exact
  1813. X    listing of what file is in which directory.  In order for the
  1814. X    Makefiles to work, all the source files must be in the proper
  1815. X    locations.
  1816. X
  1817. X    If you downloaded or ftp'd the sources from a UNIX system, the lines
  1818. X    will probably end in UNIX-style newlines, instead of the carriage
  1819. X    return and line feed pairs used by DOS.  Some programs have trouble
  1820. X    with them, so you may need to convert them (with a utility like
  1821. X    Rahul Dhesi's "flip").  Also, every file should end with an empty
  1822. X    line, because Microsoft C has a habit of ignoring the
  1823. X    last line of each file. 
  1824. X
  1825. X3.  Go to the sys\winnt directory and run the setup.bat batch file.
  1826. X    The necessary Makefile movements will be accomplished for you. It
  1827. X    will also verify that your directories are set up properly.
  1828. X
  1829. X4.  Now go to the include subdirectory to check a couple of the header
  1830. X    files there.  Things *should* work as they are, but since you have
  1831. X    probably set up your system in some sort of custom configuration
  1832. X    it doesn't hurt to check out the following:
  1833. X
  1834. X    First check config.h according to the comments to match your system and
  1835. X    desired set of features.  Mostly you need to check the WIZARD option,
  1836. X    make sure the HACKDIR is set properly.
  1837. X
  1838. X    Also check COMPRESS.
  1839. X
  1840. X    You may include all or as few of the special game features as you wish.
  1841. X
  1842. X    Also check ntconf.h, which should not need much editing. It is there that
  1843. X    you may choose to enable color text character support by leaving
  1844. X    TERMCOLOR uncommented, or disable color support by commenting out 
  1845. X    TERMCOLOR.
  1846. X
  1847. X5.  If you want to change the high score list behavior, examine the top of
  1848. X    topten.c, in the src directory.  You may want to change the definitions of
  1849. X    PERSMAX, POINTSMIN, and ENTRYMAX.  I set POINTSMIN to 51 and ENTRYMAX to
  1850. X    50 to keep the size of the score list down.
  1851. X
  1852. X6.  Go to the src directory and edit the top of your Makefile.
  1853. X    Change the setting of (GAMEDIR) to reflect the directory where
  1854. X    you want NetHack to be installed.  
  1855. X
  1856. X    ie.  GAMEDIR = \games\nethack
  1857. X
  1858. X    The directory you specify *MUST* exist for all remaining steps to be 
  1859. X    successful. Be sure the directory you want the game installed 
  1860. X    actually exists.  If it doesn't, create it now.
  1861. X
  1862. X    If you elected not to use the high-quality BSD random number routines by
  1863. X    commenting out RANDOM in ntconf.h, comment out (or set equal
  1864. X    to nothing) the RANDOM macro in your Makefile.
  1865. X
  1866. X    If you want, you can choose to have a default NetHack ICON embedded
  1867. X    into your executable. You must have first uudecoded the file
  1868. X    sys\winnt\nhico.uu into sys\winnt\nethack.ico.
  1869. X    Change the Makefile macro RESFILE to point to the second
  1870. X    choice (make the macro specify the .rbj file, rather than being set
  1871. X    equal to nothing).
  1872. X
  1873. X    If you are recompiling after patching your sources, or if you got your
  1874. X    files from somewhere other than the official distribution, "touch
  1875. X    makedefs.c" to ensure that certain files (onames.h and pm.h) are remade,
  1876. X    lest potentially troublesome timestamps fool "nmake".
  1877. X
  1878. XCompiling
  1879. X
  1880. X7.  Now that everything is set up, go to the util directory and
  1881. X    run nmake.  If you get any errors along the way then something
  1882. X    has not been set up correctly.
  1883. X
  1884. X8.  Next, go to the dat directory and run nmake (just as you did for util).
  1885. X    Once again, if you get any errors then something has not been 
  1886. X    set up correctly.
  1887. X
  1888. X9.  Finally, go to the src directory and "nmake install".  The time it takes
  1889. X    to compile depends on your particular machine of course, but you should 
  1890. X    be able to go for lunch and return to find everything finished.  The 
  1891. X    less memory, and slower your machine, the longer the lunch you may take.
  1892. X    
  1893. X    In any case, it is likely that the command prompt window where you are 
  1894. X    doing the compiling will be occupied for a quite a while.  If all 
  1895. X    goes well, you will get an NetHack executable.
  1896. X
  1897. XRunning NetHack
  1898. X
  1899. X10. Make sure the support files -- data, rumors, cmdhelp, opthelp, help, hh,
  1900. X    history, options and license -- were copied to the game directory.  If not,
  1901. X    move them there from the dat directory yourself.  
  1902. X    Assuming you are still in the src,dat, or util directory,
  1903. X    "rumors." can be created manually by entering "..\util\makedefs -r"
  1904. X    "data." can be created by entering "..\util\makedefs -d".
  1905. X
  1906. X    Make sure the file NetHack.cnf made it to your game directory.
  1907. X    If not, go to sys\winnt and copy winnt.cnf to NetHack.cnf in 
  1908. X    your game directory.  Edit NetHack.cnf to reflect your
  1909. X    particular setup and personal preferences, by following the comments.
  1910. X  
  1911. XRunning from Command Prompt
  1912. X
  1913. X11. If you are running it from the command prompt, you must first set the
  1914. X    HACKDIR environment variable to the location where the nethack 
  1915. X    executable resides:
  1916. X
  1917. X    set HACKDIR=c:\games\nethack)
  1918. X    (or whatever drive and directory you want to use)
  1919. X
  1920. X    You should also add the directory containing the NetHack executable
  1921. X    to your PATH, so that you can just type "nethack" or "nethack -umike"
  1922. X    to start it up.  Alternatively, you can explicitly invoke it with 
  1923. X    "c:\games\nethack\nethack" (specifying whatever drive and directory your
  1924. X    executable resides in) each time.
  1925. X
  1926. X
  1927. XRunning from Windows NT Program Manager
  1928. X
  1929. X12. If you will be running it by launching it from the Program Manager,
  1930. X    be sure to specify the location of your NetHack executable in the 
  1931. X    "Working Directory:" dialogue box field when creating your 
  1932. X    Program Manager Icon:
  1933. X
  1934. X    ie.  Description      :  NetHack 3.1.2 
  1935. X         Command Line     :  C:\GAMES\NETHACK\NETHACK.EXE
  1936. X         Working Directory:  C:\GAMES\NETHACK
  1937. X         Shortcut key     :
  1938. X
  1939. X13. If you did not elect to embed an ICON into the NetHack executable
  1940. X    when you built it, then you may point the program manager to the 
  1941. X    ICON of your choice using the program manager (f)ile, (p)roperties,
  1942. X    change icon option.
  1943. X
  1944. X    A NetHack icon has been provided in the file SYS\WINNT\NHICO.UU.
  1945. X    This is a uuencoded copy of the icon file, and you must use uudecode
  1946. X    to turn it into a Windows NT icon file, in order to use the icon.
  1947. X
  1948. X14. Play NetHack.  If it works, you're done!
  1949. X
  1950. XNotes:
  1951. X
  1952. X1)  To install an update of NetHack after changing something, enter "nmake"
  1953. X    from the src directory.  If you add, delete, or reorder monsters or
  1954. X    objects, or you change the format of saved level files, delete any save
  1955. X    and bones files.  (Trying to use such files sometimes produces amusing
  1956. X    confusions on the game's part, but usually crashes.)
  1957. X
  1958. X    If you made changes to any of the level compiler software, you may have
  1959. X    to delete dgn_flex.c, dgn_yacc.c, lev_flex.c, and lev_yacc.c from the
  1960. X    util directory to ensure that they are remade.
  1961. X
  1962. X2)  The executable produced by this port is a 32-bit, flat-address space, 
  1963. X    non-overlayed .exe file, which should run on any Windows NT system. 
  1964. X    It is also a rather large file:
  1965. X
  1966. X    More than 1,900,000 bytes, nethack.exe when debugging information 
  1967. X        is included in the .exe, and more than 1,200,000 bytes without.
  1968. X
  1969. X3)  If you want to use the number pad on the keyboard for movement when
  1970. X    playing the game, be sure the NUMLOCK is on.
  1971. X
  1972. X4)  A true Windows (WIN32s) version of NetHack is currently under development
  1973. X    by the PC Windows Porting team.
  1974. X
  1975. X5)  If you have comments or suggestions, feel free to drop any one of
  1976. X    us a line c/o nethack-bugs@linc.cis.upenn.edu.  From compuserve,
  1977. X    try  >INTERNET:nethack-bugs@linc.cis.upenn.edu.
  1978. END_OF_FILE
  1979. if test 10776 -ne `wc -c <'sys/winnt/Install.nt'`; then
  1980.     echo shar: \"'sys/winnt/Install.nt'\" unpacked with wrong size!
  1981. fi
  1982. # end of 'sys/winnt/Install.nt'
  1983. echo shar: End of archive 30 \(of 33\).
  1984. cp /dev/null ark30isdone
  1985. MISSING=""
  1986. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ; do
  1987.     if test ! -f ark${I}isdone ; then
  1988.     MISSING="${MISSING} ${I}"
  1989.     fi
  1990. done
  1991. if test "${MISSING}" = "" ; then
  1992.     echo You have unpacked all 33 archives.
  1993.     echo "Now execute ./patchit.sh"
  1994.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1995. else
  1996.     echo You still need to unpack the following archives:
  1997.     echo "        " ${MISSING}
  1998. fi
  1999. ##  End of shell archive.
  2000. exit 0
  2001.